Synchronize changes from branches/GpuClothAMD to trunk
Main improvements are: GPU cloth collision detection against a capsule shape ,OpenCL-OpenGL interoperability (keeping data buffers on GPU), and bug fixes Thanks to Lee Howes
This commit is contained in:
@@ -39,8 +39,11 @@ SET(BulletSoftBodyDX11Solvers_Shaders
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
ComputeBounds
|
||||
SolvePositions
|
||||
SolvePositionsSIMDBatched
|
||||
SolveCollisionsAndUpdateVelocities
|
||||
SolveCollisionsAndUpdateVelocitiesSIMDBatched
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
|
||||
@@ -68,6 +68,9 @@ protected:
|
||||
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
|
||||
buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
// At a minimum the buffer must exist
|
||||
if( buffer_desc.ByteWidth == 0 )
|
||||
buffer_desc.ByteWidth = sizeof(ElementType);
|
||||
buffer_desc.StructureByteStride = sizeof(ElementType);
|
||||
hr = m_d3dDevice->CreateBuffer(&buffer_desc, NULL, &m_Buffer);
|
||||
if( FAILED( hr ) )
|
||||
@@ -82,6 +85,8 @@ protected:
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
if( srvbuffer_desc.Buffer.ElementWidth == 0 )
|
||||
srvbuffer_desc.Buffer.ElementWidth = 1;
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
@@ -93,6 +98,8 @@ protected:
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
if( srvbuffer_desc.Buffer.ElementWidth == 0 )
|
||||
srvbuffer_desc.Buffer.ElementWidth = 1;
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
@@ -104,6 +111,8 @@ protected:
|
||||
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
|
||||
uavbuffer_desc.Buffer.NumElements = m_CPUBuffer->size();
|
||||
if( uavbuffer_desc.Buffer.NumElements == 0 )
|
||||
uavbuffer_desc.Buffer.NumElements = 1;
|
||||
hr = m_d3dDevice->CreateUnorderedAccessView(m_Buffer, &uavbuffer_desc, &m_UAV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
@@ -173,7 +182,8 @@ public:
|
||||
*/
|
||||
bool moveToGPU()
|
||||
{
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
// Reallocate if GPU size is too small
|
||||
if( (m_CPUBuffer->size() > m_gpuSize ) )
|
||||
m_onGPU = false;
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
@@ -192,16 +202,20 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
D3D11_BOX destRegion;
|
||||
destRegion.left = 0;
|
||||
destRegion.front = 0;
|
||||
destRegion.top = 0;
|
||||
destRegion.bottom = 1;
|
||||
destRegion.back = 1;
|
||||
destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
|
||||
m_d3dDeviceContext->UpdateSubresource(m_Buffer, 0, &destRegion, &((*m_CPUBuffer)[0]), 0, 0);
|
||||
if( m_gpuSize > 0 )
|
||||
{
|
||||
D3D11_BOX destRegion;
|
||||
destRegion.left = 0;
|
||||
destRegion.front = 0;
|
||||
destRegion.top = 0;
|
||||
destRegion.bottom = 1;
|
||||
destRegion.back = 1;
|
||||
destRegion.right = (m_CPUBuffer->size())*sizeof(ElementType);
|
||||
m_d3dDeviceContext->UpdateSubresource(m_Buffer, 0, &destRegion, &((*m_CPUBuffer)[0]), 0, 0);
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
@@ -19,6 +19,7 @@ subject to the following restrictions:
|
||||
#include "btSoftBodySolver_DX11.h"
|
||||
#include "btSoftBodySolverVertexBuffer_DX11.h"
|
||||
#include "BulletSoftBody/btSoftBody.h"
|
||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||
|
||||
#define MSTRINGIFY(A) #A
|
||||
static char* PrepareLinksHLSLString =
|
||||
@@ -43,6 +44,10 @@ static char* OutputToVertexArrayHLSLString =
|
||||
#include "HLSL/OutputToVertexArray.hlsl"
|
||||
static char* VSolveLinksHLSLString =
|
||||
#include "HLSL/VSolveLinks.hlsl"
|
||||
static char* ComputeBoundsHLSLString =
|
||||
#include "HLSL/ComputeBounds.hlsl"
|
||||
static char* SolveCollisionsAndUpdateVelocitiesHLSLString =
|
||||
#include "HLSL/SolveCollisionsAndUpdateVelocities.hlsl"
|
||||
|
||||
|
||||
btSoftBodyLinkDataDX11::btSoftBodyLinkDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext ) :
|
||||
@@ -545,6 +550,7 @@ void btSoftBodyTriangleDataDX11::generateBatches()
|
||||
btDX11SoftBodySolver::btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context) :
|
||||
m_dx11Device( dx11Device ),
|
||||
m_dx11Context( dx11Context ),
|
||||
dxFunctions( m_dx11Device, m_dx11Context ),
|
||||
m_linkData(m_dx11Device, m_dx11Context),
|
||||
m_vertexData(m_dx11Device, m_dx11Context),
|
||||
m_triangleData(m_dx11Device, m_dx11Context),
|
||||
@@ -554,7 +560,12 @@ btDX11SoftBodySolver::btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11Devi
|
||||
m_dx11PerClothVelocityCorrectionCoefficient( m_dx11Device, m_dx11Context, &m_perClothVelocityCorrectionCoefficient, true ),
|
||||
m_dx11PerClothLiftFactor( m_dx11Device, m_dx11Context, &m_perClothLiftFactor, true ),
|
||||
m_dx11PerClothDragFactor( m_dx11Device, m_dx11Context, &m_perClothDragFactor, true ),
|
||||
m_dx11PerClothMediumDensity( m_dx11Device, m_dx11Context, &m_perClothMediumDensity, true )
|
||||
m_dx11PerClothMediumDensity( m_dx11Device, m_dx11Context, &m_perClothMediumDensity, true ),
|
||||
m_dx11PerClothCollisionObjects( m_dx11Device, m_dx11Context, &m_perClothCollisionObjects, true ),
|
||||
m_dx11CollisionObjectDetails( m_dx11Device, m_dx11Context, &m_collisionObjectDetails, true ),
|
||||
m_dx11PerClothMinBounds( m_dx11Device, m_dx11Context, &m_perClothMinBounds, false ),
|
||||
m_dx11PerClothMaxBounds( m_dx11Device, m_dx11Context, &m_perClothMaxBounds, false ),
|
||||
m_dx11PerClothFriction( m_dx11Device, m_dx11Context, &m_perClothFriction, false )
|
||||
{
|
||||
// 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
|
||||
@@ -565,15 +576,20 @@ btDX11SoftBodySolver::btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11Devi
|
||||
}
|
||||
|
||||
btDX11SoftBodySolver::~btDX11SoftBodySolver()
|
||||
{
|
||||
releaseKernels();
|
||||
}
|
||||
|
||||
void btDX11SoftBodySolver::releaseKernels()
|
||||
{
|
||||
|
||||
SAFE_RELEASE( prepareLinksKernel.kernel );
|
||||
SAFE_RELEASE( prepareLinksKernel.constBuffer );
|
||||
SAFE_RELEASE( integrateKernel.kernel );
|
||||
SAFE_RELEASE( integrateKernel.constBuffer );
|
||||
SAFE_RELEASE( integrateKernel.kernel );
|
||||
SAFE_RELEASE( prepareLinksKernel.constBuffer );
|
||||
SAFE_RELEASE( prepareLinksKernel.kernel );
|
||||
SAFE_RELEASE( solvePositionsFromLinksKernel.constBuffer );
|
||||
SAFE_RELEASE( solvePositionsFromLinksKernel.kernel );
|
||||
SAFE_RELEASE( vSolveLinksKernel.constBuffer );
|
||||
SAFE_RELEASE( vSolveLinksKernel.kernel );
|
||||
SAFE_RELEASE( updatePositionsFromVelocitiesKernel.constBuffer );
|
||||
SAFE_RELEASE( updatePositionsFromVelocitiesKernel.kernel );
|
||||
SAFE_RELEASE( updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer );
|
||||
@@ -586,27 +602,57 @@ btDX11SoftBodySolver::~btDX11SoftBodySolver()
|
||||
SAFE_RELEASE( normalizeNormalsAndAreasKernel.kernel );
|
||||
SAFE_RELEASE( updateSoftBodiesKernel.constBuffer );
|
||||
SAFE_RELEASE( updateSoftBodiesKernel.kernel );
|
||||
SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.constBuffer );
|
||||
SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.kernel );
|
||||
SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.constBuffer );
|
||||
SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.kernel );
|
||||
|
||||
SAFE_RELEASE( solveCollisionsAndUpdateVelocitiesKernel.kernel );
|
||||
SAFE_RELEASE( solveCollisionsAndUpdateVelocitiesKernel.constBuffer );
|
||||
SAFE_RELEASE( computeBoundsKernel.kernel );
|
||||
SAFE_RELEASE( computeBoundsKernel.constBuffer );
|
||||
SAFE_RELEASE( vSolveLinksKernel.kernel );
|
||||
SAFE_RELEASE( vSolveLinksKernel.constBuffer );
|
||||
|
||||
SAFE_RELEASE( addVelocityKernel.constBuffer );
|
||||
SAFE_RELEASE( addVelocityKernel.kernel );
|
||||
SAFE_RELEASE( applyForcesKernel.constBuffer );
|
||||
SAFE_RELEASE( applyForcesKernel.kernel );
|
||||
SAFE_RELEASE( outputToVertexArrayKernel.constBuffer );
|
||||
SAFE_RELEASE( outputToVertexArrayKernel.kernel );
|
||||
SAFE_RELEASE( collideCylinderKernel.constBuffer );
|
||||
SAFE_RELEASE( collideCylinderKernel.kernel );
|
||||
|
||||
m_shadersInitialized = false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softBodies )
|
||||
void btDX11SoftBodySolver::copyBackToSoftBodies()
|
||||
{
|
||||
if( m_softBodySet.size() != softBodies.size() )
|
||||
// Move the vertex data back to the host first
|
||||
m_vertexData.moveFromAccelerator();
|
||||
|
||||
// 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() );
|
||||
}
|
||||
}
|
||||
} // btDX11SoftBodySolver::copyBackToSoftBodies
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::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();
|
||||
@@ -622,7 +668,7 @@ void btDX11SoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softB
|
||||
using Vectormath::Aos::Point3;
|
||||
|
||||
// Create SoftBody that will store the information within the solver
|
||||
btDX11AcceleratedSoftBodyInterface *newSoftBody = new btDX11AcceleratedSoftBodyInterface( softBody );
|
||||
btAcceleratedSoftBodyInterface *newSoftBody = new btAcceleratedSoftBodyInterface( softBody );
|
||||
m_softBodySet.push_back( newSoftBody );
|
||||
|
||||
m_perClothAcceleration.push_back( toVector3(softBody->getWorldInfo()->m_gravity) );
|
||||
@@ -631,6 +677,11 @@ void btDX11SoftBodySolver::optimize( btAlignedObjectArray< btSoftBody * > &softB
|
||||
m_perClothLiftFactor.push_back( softBody->m_cfg.kLF );
|
||||
m_perClothDragFactor.push_back( softBody->m_cfg.kDG );
|
||||
m_perClothMediumDensity.push_back(softBody->getWorldInfo()->air_density);
|
||||
// Simple init values. Actually we'll put 0 and -1 into them at the appropriate time
|
||||
m_perClothMinBounds.push_back( UIntVector3( 0, 0, 0 ) );
|
||||
m_perClothMaxBounds.push_back( UIntVector3( UINT_MAX, UINT_MAX, UINT_MAX ) );
|
||||
m_perClothFriction.push_back( softBody->getFriction() );
|
||||
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
|
||||
@@ -738,7 +789,11 @@ btSoftBodyTriangleData &btDX11SoftBodySolver::getTriangleData()
|
||||
|
||||
bool btDX11SoftBodySolver::checkInitialized()
|
||||
{
|
||||
return buildShaders();
|
||||
if( !m_shadersInitialized )
|
||||
if( buildShaders() )
|
||||
m_shadersInitialized = true;
|
||||
|
||||
return m_shadersInitialized;
|
||||
}
|
||||
|
||||
void btDX11SoftBodySolver::resetNormalsAndAreas( int numVertices )
|
||||
@@ -892,6 +947,7 @@ void btDX11SoftBodySolver::updateSoftBodies()
|
||||
|
||||
|
||||
normalizeNormalsAndAreas( numVertices );
|
||||
|
||||
|
||||
} // btDX11SoftBodySolver::updateSoftBodies
|
||||
|
||||
@@ -1046,6 +1102,80 @@ float btDX11SoftBodySolver::computeTriangleArea(
|
||||
return area;
|
||||
} // btDX11SoftBodySolver::computeTriangleArea
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::updateBounds()
|
||||
{
|
||||
using Vectormath::Aos::Point3;
|
||||
// Interpretation structure for float and int
|
||||
|
||||
struct FPRep {
|
||||
unsigned int mantissa : 23;
|
||||
unsigned int exponent : 8;
|
||||
unsigned int sign : 1;
|
||||
};
|
||||
union FloatAsInt
|
||||
{
|
||||
float floatValue;
|
||||
int intValue;
|
||||
unsigned int uintValue;
|
||||
FPRep fpRep;
|
||||
};
|
||||
|
||||
|
||||
// Update bounds array to min and max int values to allow easy atomics
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
m_perClothMinBounds[softBodyIndex] = UIntVector3( UINT_MAX, UINT_MAX, UINT_MAX );
|
||||
m_perClothMaxBounds[softBodyIndex] = UIntVector3( 0, 0, 0 );
|
||||
}
|
||||
|
||||
m_dx11PerClothMinBounds.moveToGPU();
|
||||
m_dx11PerClothMaxBounds.moveToGPU();
|
||||
|
||||
|
||||
computeBounds( );
|
||||
|
||||
|
||||
m_dx11PerClothMinBounds.moveFromGPU();
|
||||
m_dx11PerClothMaxBounds.moveFromGPU();
|
||||
|
||||
|
||||
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
UIntVector3 minBoundUInt = m_perClothMinBounds[softBodyIndex];
|
||||
UIntVector3 maxBoundUInt = m_perClothMaxBounds[softBodyIndex];
|
||||
|
||||
// Convert back to float
|
||||
FloatAsInt fai;
|
||||
|
||||
btVector3 minBound;
|
||||
fai.uintValue = minBoundUInt.x;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
minBound.setX( fai.floatValue );
|
||||
fai.uintValue = minBoundUInt.y;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
minBound.setY( fai.floatValue );
|
||||
fai.uintValue = minBoundUInt.z;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
minBound.setZ( fai.floatValue );
|
||||
|
||||
btVector3 maxBound;
|
||||
fai.uintValue = maxBoundUInt.x;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
maxBound.setX( fai.floatValue );
|
||||
fai.uintValue = maxBoundUInt.y;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
maxBound.setY( fai.floatValue );
|
||||
fai.uintValue = maxBoundUInt.z;
|
||||
fai.uintValue ^= (((fai.uintValue >> 31) - 1) | 0x80000000);
|
||||
maxBound.setZ( fai.floatValue );
|
||||
|
||||
// And finally assign to the soft body
|
||||
m_softBodySet[softBodyIndex]->updateBounds( minBound, maxBound );
|
||||
}
|
||||
}
|
||||
|
||||
void btDX11SoftBodySolver::updateConstants( float timeStep )
|
||||
{
|
||||
using namespace Vectormath::Aos;
|
||||
@@ -1074,6 +1204,59 @@ void btDX11SoftBodySolver::updateConstants( float timeStep )
|
||||
}
|
||||
} // btDX11SoftBodySolver::updateConstants
|
||||
|
||||
/**
|
||||
* Sort the collision object details array and generate indexing into it for the per-cloth collision object array.
|
||||
*/
|
||||
void btDX11SoftBodySolver::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 );
|
||||
|
||||
|
||||
class QuickSortCompare
|
||||
{
|
||||
public:
|
||||
|
||||
bool operator() ( const CollisionShapeDescription& a, const CollisionShapeDescription& b )
|
||||
{
|
||||
return ( a.softBodyIdentifier < b.softBodyIdentifier );
|
||||
}
|
||||
};
|
||||
|
||||
QuickSortCompare comparator;
|
||||
m_collisionObjectDetails.quickSort( comparator );
|
||||
|
||||
// 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();
|
||||
|
||||
} // btDX11SoftBodySolver::prepareCollisionConstraints
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::solveConstraints( float solverdt )
|
||||
@@ -1115,6 +1298,9 @@ void btDX11SoftBodySolver::solveConstraints( float solverdt )
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
prepareCollisionConstraints();
|
||||
|
||||
// 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
|
||||
@@ -1139,7 +1325,8 @@ void btDX11SoftBodySolver::solveConstraints( float solverdt )
|
||||
|
||||
} // for( int iteration = 0; iteration < m_numberOfPositionIterations ; ++iteration )
|
||||
|
||||
updateVelocitiesFromPositionsWithoutVelocities( 1.f/solverdt );
|
||||
// At this point assume that the force array is blank - we will overwrite it
|
||||
solveCollisionsAndUpdateVelocities( 1.f/solverdt );
|
||||
} // btDX11SoftBodySolver::solveConstraints
|
||||
|
||||
|
||||
@@ -1435,6 +1622,114 @@ void btDX11SoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities( float
|
||||
|
||||
} // btDX11SoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::computeBounds( )
|
||||
{
|
||||
ComputeBoundsCB constBuffer;
|
||||
m_vertexData.moveToAccelerator();
|
||||
|
||||
// Set the first link of the batch
|
||||
// and the batch size
|
||||
constBuffer.numNodes = m_vertexData.getNumVertices();
|
||||
constBuffer.numSoftBodies = m_softBodySet.size();
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
m_dx11Context->Map( computeBoundsKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
|
||||
memcpy( MappedResource.pData, &constBuffer, sizeof(ComputeBoundsCB) );
|
||||
m_dx11Context->Unmap( computeBoundsKernel.constBuffer, 0 );
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &computeBoundsKernel.constBuffer );
|
||||
|
||||
// Set resources and dispatch
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) );
|
||||
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_dx11PerClothMinBounds.getUAV()), NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_dx11PerClothMaxBounds.getUAV()), NULL );
|
||||
|
||||
// Execute the kernel
|
||||
m_dx11Context->CSSetShader( computeBoundsKernel.kernel, NULL, 0 );
|
||||
|
||||
int numBlocks = (constBuffer.numNodes + (128-1)) / 128;
|
||||
m_dx11Context->Dispatch(numBlocks , 1, 1 );
|
||||
|
||||
{
|
||||
// Tidy up
|
||||
ID3D11ShaderResourceView* pViewNULL = NULL;
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL );
|
||||
|
||||
ID3D11UnorderedAccessView* pUAViewNULL = NULL;
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL );
|
||||
|
||||
ID3D11Buffer *pBufferNull = NULL;
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull );
|
||||
}
|
||||
}
|
||||
|
||||
void btDX11SoftBodySolver::solveCollisionsAndUpdateVelocities( float isolverdt )
|
||||
{
|
||||
|
||||
// Copy kernel parameters to GPU
|
||||
m_vertexData.moveToAccelerator();
|
||||
m_dx11PerClothFriction.moveToGPU();
|
||||
m_dx11PerClothDampingFactor.moveToGPU();
|
||||
m_dx11PerClothCollisionObjects.moveToGPU();
|
||||
m_dx11CollisionObjectDetails.moveToGPU();
|
||||
|
||||
SolveCollisionsAndUpdateVelocitiesCB constBuffer;
|
||||
|
||||
// Set the first link of the batch
|
||||
// and the batch size
|
||||
constBuffer.numNodes = m_vertexData.getNumVertices();
|
||||
constBuffer.isolverdt = isolverdt;
|
||||
|
||||
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
m_dx11Context->Map( solveCollisionsAndUpdateVelocitiesKernel.constBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
|
||||
memcpy( MappedResource.pData, &constBuffer, sizeof(SolveCollisionsAndUpdateVelocitiesCB) );
|
||||
m_dx11Context->Unmap( solveCollisionsAndUpdateVelocitiesKernel.constBuffer, 0 );
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &solveCollisionsAndUpdateVelocitiesKernel.constBuffer );
|
||||
|
||||
// Set resources and dispatch
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11ClothIdentifier.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexPreviousPosition.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 2, 1, &(m_dx11PerClothFriction.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 3, 1, &(m_dx11PerClothDampingFactor.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 4, 1, &(m_dx11PerClothCollisionObjects.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 5, 1, &(m_dx11CollisionObjectDetails.getSRV()) );
|
||||
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(m_vertexData.m_dx11VertexForceAccumulator.getUAV()), NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &(m_vertexData.m_dx11VertexVelocity.getUAV()), NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &(m_vertexData.m_dx11VertexPosition.getUAV()), NULL );
|
||||
|
||||
// Execute the kernel
|
||||
m_dx11Context->CSSetShader( solveCollisionsAndUpdateVelocitiesKernel.kernel, NULL, 0 );
|
||||
|
||||
int numBlocks = (constBuffer.numNodes + (128-1)) / 128;
|
||||
m_dx11Context->Dispatch(numBlocks , 1, 1 );
|
||||
|
||||
{
|
||||
// Tidy up
|
||||
ID3D11ShaderResourceView* pViewNULL = NULL;
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 2, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 3, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 4, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 5, 1, &pViewNULL );
|
||||
|
||||
ID3D11UnorderedAccessView* pUAViewNULL = NULL;
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 1, 1, &pUAViewNULL, NULL );
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 2, 1, &pUAViewNULL, NULL );
|
||||
|
||||
ID3D11Buffer *pBufferNull = NULL;
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull );
|
||||
}
|
||||
|
||||
} // btDX11SoftBodySolver::solveCollisionsAndUpdateVelocities
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
@@ -1451,23 +1746,51 @@ void btDX11SoftBodySolver::updateVelocitiesFromPositionsWithoutVelocities( float
|
||||
|
||||
|
||||
|
||||
btDX11AcceleratedSoftBodyInterface *btDX11SoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody )
|
||||
btDX11SoftBodySolver::btAcceleratedSoftBodyInterface *btDX11SoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody )
|
||||
{
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btDX11AcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyInterface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void btDX11SoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
const btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * const btDX11SoftBodySolver::findSoftBodyInterface( const btSoftBody* const softBody ) const
|
||||
{
|
||||
checkInitialized();
|
||||
|
||||
btDX11AcceleratedSoftBodyInterface *currentCloth = findSoftBodyInterface( softBody );
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
{
|
||||
btAcceleratedSoftBodyInterface *softBodyInterface = m_softBodySet[softBodyIndex];
|
||||
if( softBodyInterface->getSoftBody() == softBody )
|
||||
return softBodyInterface;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int btDX11SoftBodySolver::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 btSoftBodySolverOutputDXtoCPU::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
{
|
||||
|
||||
|
||||
btSoftBodySolver *solver = softBody->getSoftBodySolver();
|
||||
btAssert( solver->getSolverType() == btSoftBodySolver::DX_SOLVER || solver->getSolverType() == btSoftBodySolver::DX_SIMD_SOLVER );
|
||||
btDX11SoftBodySolver *dxSolver = static_cast< btDX11SoftBodySolver * >( solver );
|
||||
|
||||
btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * currentCloth = dxSolver->findSoftBodyInterface( softBody );
|
||||
btSoftBodyVertexDataDX11 &vertexData( dxSolver->m_vertexData );
|
||||
|
||||
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
@@ -1475,8 +1798,8 @@ void btDX11SoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER )
|
||||
{
|
||||
// If we're doing a CPU-buffer copy must copy the data back to the host first
|
||||
m_vertexData.m_dx11VertexPosition.copyFromGPU();
|
||||
m_vertexData.m_dx11VertexNormal.copyFromGPU();
|
||||
vertexData.m_dx11VertexPosition.copyFromGPU();
|
||||
vertexData.m_dx11VertexNormal.copyFromGPU();
|
||||
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
@@ -1491,7 +1814,7 @@ void btDX11SoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Point3 position = m_vertexData.getPosition(vertexIndex);
|
||||
Vectormath::Aos::Point3 position = vertexData.getPosition(vertexIndex);
|
||||
*(vertexPointer + 0) = position.getX();
|
||||
*(vertexPointer + 1) = position.getY();
|
||||
*(vertexPointer + 2) = position.getZ();
|
||||
@@ -1506,13 +1829,82 @@ void btDX11SoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const
|
||||
|
||||
for( int vertexIndex = firstVertex; vertexIndex < lastVertex; ++vertexIndex )
|
||||
{
|
||||
Vectormath::Aos::Vector3 normal = m_vertexData.getNormal(vertexIndex);
|
||||
Vectormath::Aos::Vector3 normal = vertexData.getNormal(vertexIndex);
|
||||
*(normalPointer + 0) = normal.getX();
|
||||
*(normalPointer + 1) = normal.getY();
|
||||
*(normalPointer + 2) = normal.getZ();
|
||||
normalPointer += normalStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btDX11SoftBodySolver::outputToVertexBuffers
|
||||
|
||||
|
||||
|
||||
bool btSoftBodySolverOutputDXtoDX::checkInitialized()
|
||||
{
|
||||
if( !m_shadersInitialized )
|
||||
if( buildShaders() )
|
||||
m_shadersInitialized = true;
|
||||
|
||||
return m_shadersInitialized;
|
||||
}
|
||||
|
||||
void btSoftBodySolverOutputDXtoDX::releaseKernels()
|
||||
{
|
||||
SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.constBuffer );
|
||||
SAFE_RELEASE( outputToVertexArrayWithNormalsKernel.kernel );
|
||||
SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.constBuffer );
|
||||
SAFE_RELEASE( outputToVertexArrayWithoutNormalsKernel.kernel );
|
||||
|
||||
m_shadersInitialized = false;
|
||||
}
|
||||
|
||||
|
||||
bool btSoftBodySolverOutputDXtoDX::buildShaders()
|
||||
{
|
||||
// Ensure current kernels are released first
|
||||
releaseKernels();
|
||||
|
||||
bool returnVal = true;
|
||||
|
||||
if( m_shadersInitialized )
|
||||
return true;
|
||||
|
||||
|
||||
outputToVertexArrayWithNormalsKernel = dxFunctions.compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithNormalsKernel", sizeof(OutputToVertexArrayCB) );
|
||||
if( !outputToVertexArrayWithNormalsKernel.constBuffer)
|
||||
returnVal = false;
|
||||
outputToVertexArrayWithoutNormalsKernel = dxFunctions.compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithoutNormalsKernel", sizeof(OutputToVertexArrayCB) );
|
||||
if( !outputToVertexArrayWithoutNormalsKernel.constBuffer )
|
||||
returnVal = false;
|
||||
|
||||
|
||||
if( returnVal )
|
||||
m_shadersInitialized = true;
|
||||
|
||||
return returnVal;
|
||||
}
|
||||
|
||||
|
||||
void btSoftBodySolverOutputDXtoDX::copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer )
|
||||
{
|
||||
|
||||
|
||||
btSoftBodySolver *solver = softBody->getSoftBodySolver();
|
||||
btAssert( solver->getSolverType() == btSoftBodySolver::DX_SOLVER || solver->getSolverType() == btSoftBodySolver::DX_SIMD_SOLVER );
|
||||
btDX11SoftBodySolver *dxSolver = static_cast< btDX11SoftBodySolver * >( solver );
|
||||
checkInitialized();
|
||||
btDX11SoftBodySolver::btAcceleratedSoftBodyInterface * currentCloth = dxSolver->findSoftBodyInterface( softBody );
|
||||
btSoftBodyVertexDataDX11 &vertexData( dxSolver->m_vertexData );
|
||||
|
||||
|
||||
const int firstVertex = currentCloth->getFirstVertex();
|
||||
const int lastVertex = firstVertex + currentCloth->getNumVertices();
|
||||
|
||||
if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::CPU_BUFFER )
|
||||
{
|
||||
btSoftBodySolverOutputDXtoDX::copySoftBodyToVertexBuffer( softBody, vertexBuffer );
|
||||
} else if( vertexBuffer->getBufferType() == btVertexBufferDescriptor::DX11_BUFFER )
|
||||
{
|
||||
// Do a DX11 copy shader DX to DX copy
|
||||
@@ -1539,86 +1931,43 @@ void btDX11SoftBodySolver::copySoftBodyToVertexBuffer( const btSoftBody * const
|
||||
|
||||
// TODO: factor this out. Number of nodes is static and sdt might be, too, we can update this just once on setup
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
m_dx11Context->Map( outputToVertexArrayConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
|
||||
dxFunctions.m_dx11Context->Map( outputToVertexArrayConstBuffer, 0, D3D11_MAP_WRITE_DISCARD, 0, &MappedResource );
|
||||
memcpy( MappedResource.pData, &constBuffer, sizeof(OutputToVertexArrayCB) );
|
||||
m_dx11Context->Unmap( outputToVertexArrayConstBuffer, 0 );
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &outputToVertexArrayConstBuffer );
|
||||
dxFunctions.m_dx11Context->Unmap( outputToVertexArrayConstBuffer, 0 );
|
||||
dxFunctions.m_dx11Context->CSSetConstantBuffers( 0, 1, &outputToVertexArrayConstBuffer );
|
||||
|
||||
// Set resources and dispatch
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &(m_vertexData.m_dx11VertexPosition.getSRV()) );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &(m_vertexData.m_dx11VertexNormal.getSRV()) );
|
||||
dxFunctions.m_dx11Context->CSSetShaderResources( 0, 1, &(vertexData.m_dx11VertexPosition.getSRV()) );
|
||||
dxFunctions.m_dx11Context->CSSetShaderResources( 1, 1, &(vertexData.m_dx11VertexNormal.getSRV()) );
|
||||
|
||||
ID3D11UnorderedAccessView* dx11UAV = dx11VertexBuffer->getDX11UAV();
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(dx11UAV), NULL );
|
||||
dxFunctions.m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &(dx11UAV), NULL );
|
||||
|
||||
// Execute the kernel
|
||||
m_dx11Context->CSSetShader( outputToVertexArrayShader, NULL, 0 );
|
||||
dxFunctions.m_dx11Context->CSSetShader( outputToVertexArrayShader, NULL, 0 );
|
||||
|
||||
int numBlocks = (constBuffer.numNodes + (128-1)) / 128;
|
||||
m_dx11Context->Dispatch(numBlocks, 1, 1 );
|
||||
dxFunctions.m_dx11Context->Dispatch(numBlocks, 1, 1 );
|
||||
|
||||
{
|
||||
// Tidy up
|
||||
ID3D11ShaderResourceView* pViewNULL = NULL;
|
||||
m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL );
|
||||
m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL );
|
||||
dxFunctions.m_dx11Context->CSSetShaderResources( 0, 1, &pViewNULL );
|
||||
dxFunctions.m_dx11Context->CSSetShaderResources( 1, 1, &pViewNULL );
|
||||
|
||||
ID3D11UnorderedAccessView* pUAViewNULL = NULL;
|
||||
m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL );
|
||||
dxFunctions.m_dx11Context->CSSetUnorderedAccessViews( 0, 1, &pUAViewNULL, NULL );
|
||||
|
||||
ID3D11Buffer *pBufferNull = NULL;
|
||||
m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull );
|
||||
dxFunctions.m_dx11Context->CSSetConstantBuffers( 0, 1, &pBufferNull );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 = m_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 = m_vertexData.getNormal(vertexIndex);
|
||||
*(normalPointer + 0) = normal.getX();
|
||||
*(normalPointer + 1) = normal.getY();
|
||||
*(normalPointer + 2) = normal.getZ();
|
||||
normalPointer += normalStride;
|
||||
}
|
||||
}
|
||||
}
|
||||
} // btDX11SoftBodySolver::outputToVertexBuffers
|
||||
|
||||
|
||||
|
||||
|
||||
btDX11SoftBodySolver::KernelDesc btDX11SoftBodySolver::compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize )
|
||||
DXFunctions::KernelDesc DXFunctions::compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize, D3D10_SHADER_MACRO *compileMacros )
|
||||
{
|
||||
const char *cs5String = "cs_5_0";
|
||||
|
||||
@@ -1626,12 +1975,12 @@ btDX11SoftBodySolver::KernelDesc btDX11SoftBodySolver::compileComputeShaderFromS
|
||||
ID3DBlob* pErrorBlob = NULL;
|
||||
ID3DBlob* pBlob = NULL;
|
||||
ID3D11ComputeShader* kernelPointer = 0;
|
||||
|
||||
|
||||
hr = D3DX11CompileFromMemory(
|
||||
shaderString,
|
||||
strlen(shaderString),
|
||||
shaderName, // file name
|
||||
NULL,
|
||||
shaderName,
|
||||
compileMacros,
|
||||
NULL,
|
||||
shaderName,
|
||||
cs5String,
|
||||
@@ -1647,13 +1996,14 @@ btDX11SoftBodySolver::KernelDesc btDX11SoftBodySolver::compileComputeShaderFromS
|
||||
{
|
||||
if( pErrorBlob ) {
|
||||
btAssert( "Compilation of compute shader failed\n" );
|
||||
//OutputDebugStringA( (char*)pErrorBlob->GetBufferPointer() );
|
||||
char *debugString = (char*)pErrorBlob->GetBufferPointer();
|
||||
OutputDebugStringA( debugString );
|
||||
}
|
||||
|
||||
SAFE_RELEASE( pErrorBlob );
|
||||
SAFE_RELEASE( pBlob );
|
||||
|
||||
btDX11SoftBodySolver::KernelDesc descriptor;
|
||||
DXFunctions::KernelDesc descriptor;
|
||||
descriptor.kernel = 0;
|
||||
descriptor.constBuffer = 0;
|
||||
return descriptor;
|
||||
@@ -1663,7 +2013,7 @@ btDX11SoftBodySolver::KernelDesc btDX11SoftBodySolver::compileComputeShaderFromS
|
||||
hr = m_dx11Device->CreateComputeShader( pBlob->GetBufferPointer(), pBlob->GetBufferSize(), NULL, &kernelPointer );
|
||||
if( FAILED( hr ) )
|
||||
{
|
||||
btDX11SoftBodySolver::KernelDesc descriptor;
|
||||
DXFunctions::KernelDesc descriptor;
|
||||
descriptor.kernel = 0;
|
||||
descriptor.constBuffer = 0;
|
||||
return descriptor;
|
||||
@@ -1692,60 +2042,65 @@ btDX11SoftBodySolver::KernelDesc btDX11SoftBodySolver::compileComputeShaderFromS
|
||||
SAFE_RELEASE( pErrorBlob );
|
||||
SAFE_RELEASE( pBlob );
|
||||
|
||||
btDX11SoftBodySolver::KernelDesc descriptor;
|
||||
DXFunctions::KernelDesc descriptor;
|
||||
descriptor.kernel = kernelPointer;
|
||||
descriptor.constBuffer = constBuffer;
|
||||
return descriptor;
|
||||
} // compileComputeShader
|
||||
|
||||
|
||||
|
||||
bool btDX11SoftBodySolver::buildShaders()
|
||||
{
|
||||
// Ensure current kernels are released first
|
||||
releaseKernels();
|
||||
|
||||
bool returnVal = true;
|
||||
|
||||
if( m_shadersInitialized )
|
||||
return true;
|
||||
|
||||
prepareLinksKernel = compileComputeShaderFromString( PrepareLinksHLSLString, "PrepareLinksKernel", sizeof(PrepareLinksCB) );
|
||||
prepareLinksKernel = dxFunctions.compileComputeShaderFromString( PrepareLinksHLSLString, "PrepareLinksKernel", sizeof(PrepareLinksCB) );
|
||||
if( !prepareLinksKernel.constBuffer )
|
||||
returnVal = false;
|
||||
updatePositionsFromVelocitiesKernel = compileComputeShaderFromString( UpdatePositionsFromVelocitiesHLSLString, "UpdatePositionsFromVelocitiesKernel", sizeof(UpdatePositionsFromVelocitiesCB) );
|
||||
updatePositionsFromVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsFromVelocitiesHLSLString, "UpdatePositionsFromVelocitiesKernel", sizeof(UpdatePositionsFromVelocitiesCB) );
|
||||
if( !updatePositionsFromVelocitiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
solvePositionsFromLinksKernel = compileComputeShaderFromString( SolvePositionsHLSLString, "SolvePositionsFromLinksKernel", sizeof(SolvePositionsFromLinksKernelCB) );
|
||||
solvePositionsFromLinksKernel = dxFunctions.compileComputeShaderFromString( SolvePositionsHLSLString, "SolvePositionsFromLinksKernel", sizeof(SolvePositionsFromLinksKernelCB) );
|
||||
if( !updatePositionsFromVelocitiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
vSolveLinksKernel = compileComputeShaderFromString( VSolveLinksHLSLString, "VSolveLinksKernel", sizeof(VSolveLinksCB) );
|
||||
vSolveLinksKernel = dxFunctions.compileComputeShaderFromString( VSolveLinksHLSLString, "VSolveLinksKernel", sizeof(VSolveLinksCB) );
|
||||
if( !vSolveLinksKernel.constBuffer )
|
||||
returnVal = false;
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel = compileComputeShaderFromString( UpdateNodesHLSLString, "updateVelocitiesFromPositionsWithVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithVelocitiesCB) );
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNodesHLSLString, "updateVelocitiesFromPositionsWithVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithVelocitiesCB) );
|
||||
if( !updateVelocitiesFromPositionsWithVelocitiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel = compileComputeShaderFromString( UpdatePositionsHLSLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithoutVelocitiesCB) );
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel = dxFunctions.compileComputeShaderFromString( UpdatePositionsHLSLString, "updateVelocitiesFromPositionsWithoutVelocitiesKernel", sizeof(UpdateVelocitiesFromPositionsWithoutVelocitiesCB) );
|
||||
if( !updateVelocitiesFromPositionsWithoutVelocitiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
integrateKernel = compileComputeShaderFromString( IntegrateHLSLString, "IntegrateKernel", sizeof(IntegrateCB) );
|
||||
integrateKernel = dxFunctions.compileComputeShaderFromString( IntegrateHLSLString, "IntegrateKernel", sizeof(IntegrateCB) );
|
||||
if( !integrateKernel.constBuffer )
|
||||
returnVal = false;
|
||||
applyForcesKernel = compileComputeShaderFromString( ApplyForcesHLSLString, "ApplyForcesKernel", sizeof(ApplyForcesCB) );
|
||||
applyForcesKernel = dxFunctions.compileComputeShaderFromString( ApplyForcesHLSLString, "ApplyForcesKernel", sizeof(ApplyForcesCB) );
|
||||
if( !applyForcesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
solveCollisionsAndUpdateVelocitiesKernel = dxFunctions.compileComputeShaderFromString( SolveCollisionsAndUpdateVelocitiesHLSLString, "SolveCollisionsAndUpdateVelocitiesKernel", sizeof(SolveCollisionsAndUpdateVelocitiesCB) );
|
||||
if( !solveCollisionsAndUpdateVelocitiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
|
||||
// TODO: Rename to UpdateSoftBodies
|
||||
resetNormalsAndAreasKernel = compileComputeShaderFromString( UpdateNormalsHLSLString, "ResetNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
resetNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "ResetNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
if( !resetNormalsAndAreasKernel.constBuffer )
|
||||
returnVal = false;
|
||||
normalizeNormalsAndAreasKernel = compileComputeShaderFromString( UpdateNormalsHLSLString, "NormalizeNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
normalizeNormalsAndAreasKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "NormalizeNormalsAndAreasKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
if( !normalizeNormalsAndAreasKernel.constBuffer )
|
||||
returnVal = false;
|
||||
updateSoftBodiesKernel = compileComputeShaderFromString( UpdateNormalsHLSLString, "UpdateSoftBodiesKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
updateSoftBodiesKernel = dxFunctions.compileComputeShaderFromString( UpdateNormalsHLSLString, "UpdateSoftBodiesKernel", sizeof(UpdateSoftBodiesCB) );
|
||||
if( !updateSoftBodiesKernel.constBuffer )
|
||||
returnVal = false;
|
||||
outputToVertexArrayWithNormalsKernel = compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithNormalsKernel", sizeof(OutputToVertexArrayCB) );
|
||||
if( !outputToVertexArrayWithNormalsKernel.constBuffer )
|
||||
returnVal = false;
|
||||
outputToVertexArrayWithoutNormalsKernel = compileComputeShaderFromString( OutputToVertexArrayHLSLString, "OutputToVertexArrayWithoutNormalsKernel", sizeof(OutputToVertexArrayCB) );
|
||||
if( !outputToVertexArrayWithoutNormalsKernel.constBuffer )
|
||||
|
||||
computeBoundsKernel = dxFunctions.compileComputeShaderFromString( ComputeBoundsHLSLString, "ComputeBoundsKernel", sizeof(ComputeBoundsCB) );
|
||||
if( !computeBoundsKernel.constBuffer )
|
||||
returnVal = false;
|
||||
|
||||
|
||||
@@ -1757,8 +2112,76 @@ bool btDX11SoftBodySolver::buildShaders()
|
||||
}
|
||||
|
||||
|
||||
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 btDX11SoftBodySolver::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 btDX11SoftBodySolver::processCollision( btSoftBody*, btSoftBody* )
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Add the collision object to the set to deal with for a particular soft body
|
||||
void btDX11SoftBodySolver::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
|
||||
CollisionShapeDescription newCollisionShapeDescription;
|
||||
newCollisionShapeDescription.softBodyIdentifier = softBodyIndex;
|
||||
newCollisionShapeDescription.collisionShapeType = shapeType;
|
||||
// TODO: May need to transpose this matrix either here or in HLSL
|
||||
newCollisionShapeDescription.shapeTransform = toTransform3(collisionObject->getWorldTransform());
|
||||
btCapsuleShape *capsule = static_cast<btCapsuleShape*>( collisionShape );
|
||||
newCollisionShapeDescription.radius = capsule->getRadius();
|
||||
newCollisionShapeDescription.halfHeight = capsule->getHalfHeight();
|
||||
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");
|
||||
}
|
||||
} // btDX11SoftBodySolver::processCollision
|
||||
|
||||
|
||||
|
||||
void btDX11SoftBodySolver::predictMotion( float timeStep )
|
||||
{
|
||||
// Clear the collision shape array for the next frame
|
||||
// Ensure that the DX11 ones are moved off the device so they will be updated correctly
|
||||
m_dx11CollisionObjectDetails.changedOnCPU();
|
||||
m_dx11PerClothCollisionObjects.changedOnCPU();
|
||||
m_collisionObjectDetails.clear();
|
||||
|
||||
// Fill the force arrays with current acceleration data etc
|
||||
m_perClothWindVelocity.resize( m_softBodySet.size() );
|
||||
for( int softBodyIndex = 0; softBodyIndex < m_softBodySet.size(); ++softBodyIndex )
|
||||
@@ -1774,6 +2197,12 @@ void btDX11SoftBodySolver::predictMotion( float timeStep )
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
|
||||
@@ -26,184 +26,20 @@ subject to the following restrictions:
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btDX11AcceleratedSoftBodyInterface
|
||||
class DXFunctions
|
||||
{
|
||||
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:
|
||||
btDX11AcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
// 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 )
|
||||
ID3D11Device * m_dx11Device;
|
||||
ID3D11DeviceContext* m_dx11Context;
|
||||
|
||||
DXFunctions( ID3D11Device *dx11Device, ID3D11DeviceContext* dx11Context) :
|
||||
m_dx11Device( dx11Device ),
|
||||
m_dx11Context( dx11Context )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
#if 0
|
||||
void setAcceleration( Vectormath::Aos::Vector3 acceleration )
|
||||
{
|
||||
m_currentSolver->setPerClothAcceleration( m_clothIdentifier, acceleration );
|
||||
}
|
||||
|
||||
void setWindVelocity( Vectormath::Aos::Vector3 windVelocity )
|
||||
{
|
||||
m_currentSolver->setPerClothWindVelocity( m_clothIdentifier, windVelocity );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the density of the air in which the cloth is situated.
|
||||
*/
|
||||
void setAirDensity( btScalar density )
|
||||
{
|
||||
m_currentSolver->setPerClothMediumDensity( m_clothIdentifier, static_cast<float>(density) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a collision object to this soft body.
|
||||
*/
|
||||
void addCollisionObject( btCollisionObject *collisionObject )
|
||||
{
|
||||
m_currentSolver->addCollisionObjectForSoftBody( m_clothIdentifier, collisionObject );
|
||||
}
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
class btDX11SoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
public:
|
||||
|
||||
|
||||
class KernelDesc
|
||||
{
|
||||
protected:
|
||||
@@ -226,6 +62,238 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate KernelDesc object.
|
||||
*/
|
||||
KernelDesc compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize, D3D10_SHADER_MACRO *compileMacros = 0 );
|
||||
|
||||
};
|
||||
|
||||
class btDX11SoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
/**
|
||||
* Entry in the collision shape array.
|
||||
* Specifies the shape type, the transform matrix and the necessary details of the collisionShape.
|
||||
*/
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
Vectormath::Aos::Transform3 shapeTransform;
|
||||
Vectormath::Aos::Vector3 linearVelocity;
|
||||
Vectormath::Aos::Vector3 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
// Both needed for capsule
|
||||
float radius;
|
||||
float halfHeight;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
CollisionShapeDescription()
|
||||
{
|
||||
collisionShapeType = 0;
|
||||
margin = 0;
|
||||
friction = 0;
|
||||
}
|
||||
};
|
||||
|
||||
struct UIntVector3
|
||||
{
|
||||
UIntVector3()
|
||||
{
|
||||
x = 0;
|
||||
y = 0;
|
||||
z = 0;
|
||||
_padding = 0;
|
||||
}
|
||||
|
||||
UIntVector3( unsigned int x_, unsigned int y_, unsigned int z_ )
|
||||
{
|
||||
x = x_;
|
||||
y = y_;
|
||||
z = z_;
|
||||
_padding = 0;
|
||||
}
|
||||
|
||||
unsigned int x;
|
||||
unsigned int y;
|
||||
unsigned int z;
|
||||
unsigned int _padding;
|
||||
};
|
||||
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
CollisionObjectIndices( int f, int e )
|
||||
{
|
||||
firstObject = f;
|
||||
endObject = e;
|
||||
}
|
||||
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
struct PrepareLinksCB
|
||||
{
|
||||
@@ -284,20 +352,6 @@ public:
|
||||
};
|
||||
|
||||
|
||||
struct OutputToVertexArrayCB
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
struct ApplyForcesCB
|
||||
{
|
||||
unsigned int numNodes;
|
||||
@@ -326,17 +380,38 @@ public:
|
||||
int padding;
|
||||
};
|
||||
|
||||
struct ComputeBoundsCB
|
||||
{
|
||||
int numNodes;
|
||||
int numSoftBodies;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
private:
|
||||
struct SolveCollisionsAndUpdateVelocitiesCB
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float isolverdt;
|
||||
int padding0;
|
||||
int padding1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
protected:
|
||||
ID3D11Device * m_dx11Device;
|
||||
ID3D11DeviceContext* m_dx11Context;
|
||||
|
||||
|
||||
|
||||
DXFunctions dxFunctions;
|
||||
public:
|
||||
/** Link data for all cloths. Note that this will be sorted batch-wise for efficient computation and m_linkAddresses will maintain the addressing. */
|
||||
btSoftBodyLinkDataDX11 m_linkData;
|
||||
btSoftBodyVertexDataDX11 m_vertexData;
|
||||
btSoftBodyTriangleDataDX11 m_triangleData;
|
||||
|
||||
|
||||
protected:
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
@@ -346,7 +421,7 @@ private:
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btDX11AcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
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.
|
||||
@@ -380,24 +455,59 @@ private:
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btDX11Buffer<float> m_dx11PerClothMediumDensity;
|
||||
|
||||
KernelDesc prepareLinksKernel;
|
||||
KernelDesc solvePositionsFromLinksKernel;
|
||||
KernelDesc vSolveLinksKernel;
|
||||
KernelDesc integrateKernel;
|
||||
KernelDesc addVelocityKernel;
|
||||
KernelDesc updatePositionsFromVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
KernelDesc resetNormalsAndAreasKernel;
|
||||
KernelDesc normalizeNormalsAndAreasKernel;
|
||||
KernelDesc updateSoftBodiesKernel;
|
||||
KernelDesc outputToVertexArrayWithNormalsKernel;
|
||||
KernelDesc outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
/**
|
||||
* Collision shape details: pair of index of first collision shape for the cloth and number of collision objects.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionObjectIndices > m_perClothCollisionObjects;
|
||||
btDX11Buffer<CollisionObjectIndices> m_dx11PerClothCollisionObjects;
|
||||
|
||||
KernelDesc outputToVertexArrayKernel;
|
||||
KernelDesc applyForcesKernel;
|
||||
KernelDesc collideSphereKernel;
|
||||
KernelDesc collideCylinderKernel;
|
||||
/**
|
||||
* Collision shapes being passed across to the cloths in this solver.
|
||||
*/
|
||||
btAlignedObjectArray< CollisionShapeDescription > m_collisionObjectDetails;
|
||||
btDX11Buffer< CollisionShapeDescription > m_dx11CollisionObjectDetails;
|
||||
|
||||
/**
|
||||
* Minimum bounds for each cloth.
|
||||
* Updated by GPU and returned for use by broad phase.
|
||||
* These are int vectors as a reminder that they store the int representation of a float, not a float.
|
||||
* Bit 31 is inverted - is floats are stored with int-sortable values.
|
||||
*/
|
||||
btAlignedObjectArray< UIntVector3 > m_perClothMinBounds;
|
||||
btDX11Buffer< UIntVector3 > m_dx11PerClothMinBounds;
|
||||
|
||||
/**
|
||||
* Maximum bounds for each cloth.
|
||||
* Updated by GPU and returned for use by broad phase.
|
||||
* These are int vectors as a reminder that they store the int representation of a float, not a float.
|
||||
* Bit 31 is inverted - is floats are stored with int-sortable values.
|
||||
*/
|
||||
btAlignedObjectArray< UIntVector3 > m_perClothMaxBounds;
|
||||
btDX11Buffer< UIntVector3 > m_dx11PerClothMaxBounds;
|
||||
|
||||
|
||||
/**
|
||||
* Friction coefficient for each cloth
|
||||
*/
|
||||
btAlignedObjectArray< float > m_perClothFriction;
|
||||
btDX11Buffer< float > m_dx11PerClothFriction;
|
||||
|
||||
DXFunctions::KernelDesc prepareLinksKernel;
|
||||
DXFunctions::KernelDesc solvePositionsFromLinksKernel;
|
||||
DXFunctions::KernelDesc vSolveLinksKernel;
|
||||
DXFunctions::KernelDesc integrateKernel;
|
||||
DXFunctions::KernelDesc addVelocityKernel;
|
||||
DXFunctions::KernelDesc updatePositionsFromVelocitiesKernel;
|
||||
DXFunctions::KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
DXFunctions::KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
DXFunctions::KernelDesc solveCollisionsAndUpdateVelocitiesKernel;
|
||||
DXFunctions::KernelDesc resetNormalsAndAreasKernel;
|
||||
DXFunctions::KernelDesc normalizeNormalsAndAreasKernel;
|
||||
DXFunctions::KernelDesc computeBoundsKernel;
|
||||
DXFunctions::KernelDesc updateSoftBodiesKernel;
|
||||
|
||||
DXFunctions::KernelDesc applyForcesKernel;
|
||||
|
||||
|
||||
/**
|
||||
@@ -410,12 +520,7 @@ private:
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate KernelDesc object.
|
||||
*/
|
||||
KernelDesc compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize );
|
||||
|
||||
bool buildShaders();
|
||||
virtual bool buildShaders();
|
||||
|
||||
void resetNormalsAndAreas( int numVertices );
|
||||
|
||||
@@ -423,19 +528,20 @@ private:
|
||||
|
||||
void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
|
||||
|
||||
void prepareCollisionConstraints();
|
||||
|
||||
Vectormath::Aos::Vector3 ProjectOnAxis( const Vectormath::Aos::Vector3 &v, const Vectormath::Aos::Vector3 &a );
|
||||
|
||||
void ApplyClampedForce( float solverdt, const Vectormath::Aos::Vector3 &force, const Vectormath::Aos::Vector3 &vertexVelocity, float inverseMass, Vectormath::Aos::Vector3 &vertexForce );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
btDX11AcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
virtual void updateConstants( float timeStep );
|
||||
int findSoftBodyIndex( const btSoftBody* const softBody );
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
virtual void prepareLinks();
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
@@ -443,14 +549,27 @@ private:
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
void computeBounds( );
|
||||
void solveCollisionsAndUpdateVelocities( float isolverdt );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
void updateBounds();
|
||||
|
||||
|
||||
void releaseKernels();
|
||||
|
||||
public:
|
||||
btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context);
|
||||
|
||||
virtual ~btDX11SoftBodySolver();
|
||||
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return DX_SOLVER;
|
||||
}
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
@@ -461,19 +580,94 @@ public:
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 );
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
|
||||
|
||||
virtual void copyBackToSoftBodies();
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
|
||||
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 DX to CPU version.
|
||||
*/
|
||||
class btSoftBodySolverOutputDXtoCPU : public btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
|
||||
public:
|
||||
btSoftBodySolverOutputDXtoCPU()
|
||||
{
|
||||
}
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
/**
|
||||
* Class to manage movement of data from a solver to a given target.
|
||||
* This version is the DX to DX version and subclasses DX to CPU so that it works for that too.
|
||||
*/
|
||||
class btSoftBodySolverOutputDXtoDX : public btSoftBodySolverOutputDXtoCPU
|
||||
{
|
||||
protected:
|
||||
struct OutputToVertexArrayCB
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
DXFunctions dxFunctions;
|
||||
DXFunctions::KernelDesc outputToVertexArrayWithNormalsKernel;
|
||||
DXFunctions::KernelDesc outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
bool checkInitialized();
|
||||
bool buildShaders();
|
||||
void releaseKernels();
|
||||
|
||||
public:
|
||||
btSoftBodySolverOutputDXtoDX(ID3D11Device *dx11Device, ID3D11DeviceContext* dx11Context) :
|
||||
dxFunctions( dx11Device, dx11Context )
|
||||
{
|
||||
m_shadersInitialized = false;
|
||||
}
|
||||
|
||||
~btSoftBodySolverOutputDXtoDX()
|
||||
{
|
||||
releaseKernels();
|
||||
}
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -14,7 +14,7 @@ subject to the following restrictions:
|
||||
*/
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolver_DX11.h"
|
||||
#include "btSoftBodySolverVertexBuffer_DX11.h"
|
||||
#include "btSoftBodySolverLinkData_DX11SIMDAware.h"
|
||||
#include "btSoftBodySolverVertexData_DX11.h"
|
||||
@@ -24,176 +24,9 @@ subject to the following restrictions:
|
||||
#ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
|
||||
class btDX11SIMDAwareSoftBodySolver : public btSoftBodySolver
|
||||
class btDX11SIMDAwareSoftBodySolver : public btDX11SoftBodySolver
|
||||
{
|
||||
public:
|
||||
|
||||
/**
|
||||
* 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()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class KernelDesc
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
public:
|
||||
ID3D11ComputeShader* kernel;
|
||||
ID3D11Buffer* constBuffer;
|
||||
|
||||
KernelDesc()
|
||||
{
|
||||
kernel = 0;
|
||||
constBuffer = 0;
|
||||
}
|
||||
|
||||
virtual ~KernelDesc()
|
||||
{
|
||||
// TODO: this should probably destroy its kernel but we need to be careful
|
||||
// in case KernelDescs are copied
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
struct SolvePositionsFromLinksKernelCB
|
||||
{
|
||||
int startWave;
|
||||
@@ -202,230 +35,46 @@ public:
|
||||
float ti;
|
||||
};
|
||||
|
||||
struct IntegrateCB
|
||||
{
|
||||
int numNodes;
|
||||
float solverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdatePositionsFromVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float solverSDT;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateVelocitiesFromPositionsWithoutVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateVelocitiesFromPositionsWithVelocitiesCB
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct UpdateSoftBodiesCB
|
||||
{
|
||||
int numNodes;
|
||||
int startFace;
|
||||
int numFaces;
|
||||
float epsilon;
|
||||
};
|
||||
|
||||
|
||||
struct OutputToVertexArrayCB
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
struct ApplyForcesCB
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float solverdt;
|
||||
float epsilon;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
struct AddVelocityCB
|
||||
{
|
||||
int startNode;
|
||||
int lastNode;
|
||||
float velocityX;
|
||||
float velocityY;
|
||||
float velocityZ;
|
||||
int padding1;
|
||||
int padding2;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
|
||||
private:
|
||||
ID3D11Device * m_dx11Device;
|
||||
ID3D11DeviceContext* m_dx11Context;
|
||||
|
||||
|
||||
/** Link data for all cloths. Note that this will be sorted batch-wise for efficient computation and m_linkAddresses will maintain the addressing. */
|
||||
btSoftBodyLinkDataDX11SIMDAware m_linkData;
|
||||
btSoftBodyVertexDataDX11 m_vertexData;
|
||||
btSoftBodyTriangleDataDX11 m_triangleData;
|
||||
|
||||
/** Variable to define whether we need to update solver constants on the next iteration */
|
||||
bool m_updateSolverConstants;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
/**
|
||||
* Cloths owned by this solver.
|
||||
* Only our cloths are in this array.
|
||||
*/
|
||||
btAlignedObjectArray< btAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
virtual bool buildShaders();
|
||||
|
||||
/** 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;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11PerClothAcceleration;
|
||||
|
||||
/** 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;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11PerClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
btDX11Buffer<float> m_dx11PerClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
btDX11Buffer<float> m_dx11PerClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btDX11Buffer<float> m_dx11PerClothMediumDensity;
|
||||
|
||||
KernelDesc solvePositionsFromLinksKernel;
|
||||
KernelDesc integrateKernel;
|
||||
KernelDesc addVelocityKernel;
|
||||
KernelDesc updatePositionsFromVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
KernelDesc updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
KernelDesc resetNormalsAndAreasKernel;
|
||||
KernelDesc normalizeNormalsAndAreasKernel;
|
||||
KernelDesc updateSoftBodiesKernel;
|
||||
KernelDesc outputToVertexArrayWithNormalsKernel;
|
||||
KernelDesc outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
KernelDesc outputToVertexArrayKernel;
|
||||
KernelDesc applyForcesKernel;
|
||||
KernelDesc collideSphereKernel;
|
||||
KernelDesc collideCylinderKernel;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
virtual void integrate( float solverdt );
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate KernelDesc object.
|
||||
*/
|
||||
KernelDesc compileComputeShaderFromString( const char* shaderString, const char* shaderName, int constBufferSize, D3D10_SHADER_MACRO *compileMacros = 0 );
|
||||
|
||||
bool buildShaders();
|
||||
|
||||
void resetNormalsAndAreas( int numVertices );
|
||||
|
||||
void normalizeNormalsAndAreas( int numVertices );
|
||||
|
||||
void executeUpdateSoftBodies( int firstTriangle, int numTriangles );
|
||||
|
||||
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 );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
void solveLinksForVelocity( int startLink, int numLinks, float kst );
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
void releaseKernels();
|
||||
|
||||
|
||||
public:
|
||||
btDX11SIMDAwareSoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context);
|
||||
|
||||
virtual ~btDX11SIMDAwareSoftBodySolver();
|
||||
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
virtual bool checkInitialized();
|
||||
|
||||
virtual void updateSoftBodies( );
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies );
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
virtual void predictMotion( float solverdt );
|
||||
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody *const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return DX_SIMD_SOLVER;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
|
||||
Reference in New Issue
Block a user