mirror of
https://github.com/Ragora/T2-CPP.git
synced 2026-03-26 15:49:09 +00:00
Ported Bullet to the mod loader system; needs further work
This commit is contained in:
parent
527474ff24
commit
06810b6cca
353 changed files with 80265 additions and 0 deletions
|
|
@ -0,0 +1,727 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
#define BT_SOFT_BODY_SOLVER_DATA_H
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
|
||||
class btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a link as a set of three indices into the vertex array.
|
||||
*/
|
||||
class LinkNodePair
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
|
||||
LinkNodePair()
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
}
|
||||
|
||||
LinkNodePair( int v0, int v1 )
|
||||
{
|
||||
vertex0 = v0;
|
||||
vertex1 = v1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class describing a link for input into the system.
|
||||
*/
|
||||
class LinkDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
float m_linkLinearStiffness;
|
||||
float m_linkStrength;
|
||||
|
||||
public:
|
||||
|
||||
LinkDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_linkLinearStiffness = 1.0;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_linkLinearStiffness = linkLinearStiffness;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkNodePair getVertexPair() const
|
||||
{
|
||||
LinkNodePair nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void setVertex0( int vertex )
|
||||
{
|
||||
m_vertex0 = vertex;
|
||||
}
|
||||
|
||||
void setVertex1( int vertex )
|
||||
{
|
||||
m_vertex1 = vertex;
|
||||
}
|
||||
|
||||
void setLinkLinearStiffness( float linearStiffness )
|
||||
{
|
||||
m_linkLinearStiffness = linearStiffness;
|
||||
}
|
||||
|
||||
void setLinkStrength( float strength )
|
||||
{
|
||||
m_linkStrength = strength;
|
||||
}
|
||||
|
||||
int getVertex0() const
|
||||
{
|
||||
return m_vertex0;
|
||||
}
|
||||
|
||||
int getVertex1() const
|
||||
{
|
||||
return m_vertex1;
|
||||
}
|
||||
|
||||
float getLinkStrength() const
|
||||
{
|
||||
return m_linkStrength;
|
||||
}
|
||||
|
||||
float getLinkLinearStiffness() const
|
||||
{
|
||||
return m_linkLinearStiffness;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
|
||||
btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
|
||||
btAlignedObjectArray< float > m_linkStrength; // Strength of each link
|
||||
// (inverseMassA + inverseMassB)/ linear stiffness coefficient
|
||||
btAlignedObjectArray< float > m_linksMassLSC;
|
||||
btAlignedObjectArray< float > m_linksRestLengthSquared;
|
||||
// Current vector length of link
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength;
|
||||
// 1/(current length * current length * massLSC)
|
||||
btAlignedObjectArray< float > m_linksLengthRatio;
|
||||
btAlignedObjectArray< float > m_linksRestLength;
|
||||
btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
public:
|
||||
btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_links.resize(0);
|
||||
m_linkStrength.resize(0);
|
||||
m_linksMassLSC.resize(0);
|
||||
m_linksRestLengthSquared.resize(0);
|
||||
m_linksLengthRatio.resize(0);
|
||||
m_linksRestLength.resize(0);
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize(0);
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_links.size();
|
||||
}
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks )
|
||||
{
|
||||
int previousSize = m_links.size();
|
||||
int newSize = previousSize + numLinks;
|
||||
|
||||
// Resize all the arrays that store link data
|
||||
m_links.resize( newSize );
|
||||
m_linkStrength.resize( newSize );
|
||||
m_linksMassLSC.resize( newSize );
|
||||
m_linksRestLengthSquared.resize( newSize );
|
||||
m_linksCLength.resize( newSize );
|
||||
m_linksLengthRatio.resize( newSize );
|
||||
m_linksRestLength.resize( newSize );
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize( newSize );
|
||||
}
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex )
|
||||
{
|
||||
m_links[linkIndex] = link.getVertexPair();
|
||||
m_linkStrength[linkIndex] = link.getLinkStrength();
|
||||
m_linksMassLSC[linkIndex] = 0.f;
|
||||
m_linksRestLengthSquared[linkIndex] = 0.f;
|
||||
m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_linksLengthRatio[linkIndex] = 0.f;
|
||||
m_linksRestLength[linkIndex] = 0.f;
|
||||
m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return reference to the vertex index pair for link linkIndex as stored on the host.
|
||||
*/
|
||||
LinkNodePair &getVertexPair( int linkIndex )
|
||||
{
|
||||
return m_links[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to strength of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getStrength( int linkIndex )
|
||||
{
|
||||
return m_linkStrength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the strength of the link corrected for link sorting.
|
||||
* This is important if we are using data on an accelerator which has the data sorted in some fashion.
|
||||
*/
|
||||
virtual float &getStrengthCorrected( int linkIndex )
|
||||
{
|
||||
return getStrength( linkIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the rest length of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLength( int linkIndex )
|
||||
{
|
||||
return m_linksRestLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to linear stiffness coefficient for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinearStiffnessCoefficient( int linkIndex )
|
||||
{
|
||||
return m_linksMaterialLinearStiffnessCoefficient[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the MassLSC value for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getMassLSC( int linkIndex )
|
||||
{
|
||||
return m_linksMassLSC[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to rest length squared for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLengthSquared( int linkIndex )
|
||||
{
|
||||
return m_linksRestLengthSquared[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to current length of link linkIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex )
|
||||
{
|
||||
return m_linksCLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the link length ratio from for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinkLengthRatio( int linkIndex )
|
||||
{
|
||||
return m_linksLengthRatio[linkIndex];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for vertex data information.
|
||||
* By wrapping it like this we stand a good chance of being able to optimise for storage format easily.
|
||||
* It should also help us make sure all the data structures remain consistent.
|
||||
*/
|
||||
class btSoftBodyVertexData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class describing a vertex for input into the system.
|
||||
*/
|
||||
class VertexDescription
|
||||
{
|
||||
private:
|
||||
Vectormath::Aos::Point3 m_position;
|
||||
/** Inverse mass. If this is 0f then the mass was 0 because that simplifies calculations. */
|
||||
float m_inverseMass;
|
||||
|
||||
public:
|
||||
VertexDescription()
|
||||
{
|
||||
m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
|
||||
{
|
||||
m_position = position;
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
void setPosition( const Vectormath::Aos::Point3 &position )
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
void setInverseMass( float inverseMass )
|
||||
{
|
||||
m_inverseMass = inverseMass;
|
||||
}
|
||||
|
||||
void setMass( float mass )
|
||||
{
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
Vectormath::Aos::Point3 getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
float getInverseMass() const
|
||||
{
|
||||
return m_inverseMass;
|
||||
}
|
||||
|
||||
float getMass() const
|
||||
{
|
||||
if( m_inverseMass == 0.f )
|
||||
return 0.f;
|
||||
else
|
||||
return 1.0f/m_inverseMass;
|
||||
}
|
||||
};
|
||||
protected:
|
||||
|
||||
// identifier for the individual cloth
|
||||
// For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices
|
||||
// For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining
|
||||
// per-cloth data
|
||||
// For sorting etc it might also be helpful to be able to use in-array data such as this.
|
||||
btAlignedObjectArray< int > m_clothIdentifier;
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity; // Velocity
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator; // Force accumulator
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal; // Normals
|
||||
btAlignedObjectArray< float > m_vertexInverseMass; // Inverse mass
|
||||
btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex
|
||||
btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex
|
||||
|
||||
public:
|
||||
btSoftBodyVertexData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyVertexData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_clothIdentifier.resize(0);
|
||||
m_vertexPosition.resize(0);
|
||||
m_vertexPreviousPosition.resize(0);
|
||||
m_vertexVelocity.resize(0);
|
||||
m_vertexForceAccumulator.resize(0);
|
||||
m_vertexNormal.resize(0);
|
||||
m_vertexInverseMass.resize(0);
|
||||
m_vertexArea.resize(0);
|
||||
m_vertexTriangleCount.resize(0);
|
||||
}
|
||||
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_vertexPosition.size();
|
||||
}
|
||||
|
||||
int getClothIdentifier( int vertexIndex )
|
||||
{
|
||||
return m_clothIdentifier[vertexIndex];
|
||||
}
|
||||
|
||||
void setVertexAt( const VertexDescription &vertex, int vertexIndex )
|
||||
{
|
||||
m_vertexPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexPreviousPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexInverseMass[vertexIndex] = vertex.getInverseMass();
|
||||
m_vertexArea[vertexIndex] = 0.f;
|
||||
m_vertexTriangleCount[vertexIndex] = 0;
|
||||
}
|
||||
|
||||
/** Create numVertices new vertices for cloth clothIdentifier */
|
||||
void createVertices( int numVertices, int clothIdentifier )
|
||||
{
|
||||
int previousSize = m_vertexPosition.size();
|
||||
int newSize = previousSize + numVertices;
|
||||
|
||||
// Resize all the arrays that store vertex data
|
||||
m_clothIdentifier.resize( newSize );
|
||||
m_vertexPosition.resize( newSize );
|
||||
m_vertexPreviousPosition.resize( newSize );
|
||||
m_vertexVelocity.resize( newSize );
|
||||
m_vertexForceAccumulator.resize( newSize );
|
||||
m_vertexNormal.resize( newSize );
|
||||
m_vertexInverseMass.resize( newSize );
|
||||
m_vertexArea.resize( newSize );
|
||||
m_vertexTriangleCount.resize( newSize );
|
||||
|
||||
for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex )
|
||||
m_clothIdentifier[vertexIndex] = clothIdentifier;
|
||||
}
|
||||
|
||||
// Get and set methods in header so they can be inlined
|
||||
|
||||
/**
|
||||
* Return a reference to the position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the previous position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPreviousPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the velocity of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getVelocity( int vertexIndex )
|
||||
{
|
||||
return m_vertexVelocity[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the force accumulator of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex )
|
||||
{
|
||||
return m_vertexForceAccumulator[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the normal of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int vertexIndex )
|
||||
{
|
||||
return m_vertexNormal[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the inverse mass of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
float &getInverseMass( int vertexIndex )
|
||||
{
|
||||
return m_vertexInverseMass[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the area controlled by this vertex.
|
||||
*/
|
||||
float &getArea( int vertexIndex )
|
||||
{
|
||||
return m_vertexArea[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the array of how many triangles touch each vertex.
|
||||
*/
|
||||
int &getTriangleCount( int vertexIndex )
|
||||
{
|
||||
return m_vertexTriangleCount[vertexIndex];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions()
|
||||
{
|
||||
return m_vertexPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a triangle as a set of three indices into the
|
||||
* vertex array.
|
||||
*/
|
||||
class TriangleNodeSet
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
int vertex2;
|
||||
int _padding;
|
||||
|
||||
TriangleNodeSet( )
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
vertex2 = 0;
|
||||
_padding = -1;
|
||||
}
|
||||
|
||||
TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
vertex0 = newVertex0;
|
||||
vertex1 = newVertex1;
|
||||
vertex2 = newVertex2;
|
||||
}
|
||||
};
|
||||
|
||||
class TriangleDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
int m_vertex2;
|
||||
|
||||
public:
|
||||
TriangleDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_vertex2 = 0;
|
||||
}
|
||||
|
||||
TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_vertex2 = newVertex2;
|
||||
}
|
||||
|
||||
TriangleNodeSet getVertexSet() const
|
||||
{
|
||||
btSoftBodyTriangleData::TriangleNodeSet nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
nodes.vertex2 = m_vertex2;
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
btAlignedObjectArray< TriangleNodeSet > m_vertexIndices;
|
||||
btAlignedObjectArray< float > m_area;
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyTriangleData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_vertexIndices.resize(0);
|
||||
m_area.resize(0);
|
||||
m_normal.resize(0);
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_vertexIndices.size();
|
||||
}
|
||||
|
||||
virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
|
||||
{
|
||||
m_vertexIndices[triangleIndex] = triangle.getVertexSet();
|
||||
}
|
||||
|
||||
virtual void createTriangles( int numTriangles )
|
||||
{
|
||||
int previousSize = m_vertexIndices.size();
|
||||
int newSize = previousSize + numTriangles;
|
||||
|
||||
// Resize all the arrays that store triangle data
|
||||
m_vertexIndices.resize( newSize );
|
||||
m_area.resize( newSize );
|
||||
m_normal.resize( newSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vertex index set for triangle triangleIndex as stored on the host.
|
||||
*/
|
||||
const TriangleNodeSet &getVertexSet( int triangleIndex )
|
||||
{
|
||||
return m_vertexIndices[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the triangle area.
|
||||
*/
|
||||
float &getTriangleArea( int triangleIndex )
|
||||
{
|
||||
return m_area[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the normal vector for this triangle.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
|
||||
{
|
||||
return m_normal[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
|
||||
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
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"
|
||||
|
||||
|
||||
|
||||
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.
|
||||
*/
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
Vectormath::Aos::Transform3 shapeTransform;
|
||||
union
|
||||
{
|
||||
struct Sphere
|
||||
{
|
||||
float radius;
|
||||
} sphere;
|
||||
struct Capsule
|
||||
{
|
||||
float radius;
|
||||
float halfHeight;
|
||||
} capsule;
|
||||
} shapeInformation;
|
||||
|
||||
CollisionShapeDescription()
|
||||
{
|
||||
collisionShapeType = 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
#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
|
||||
};
|
||||
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
|
||||
|
||||
btSoftBodyLinkData m_linkData;
|
||||
btSoftBodyVertexData m_vertexData;
|
||||
btSoftBodyTriangleData m_triangleData;
|
||||
|
||||
/** 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< CollisionShapeDescription > 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 );
|
||||
btAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
|
||||
public:
|
||||
btCPUSoftBodySolver();
|
||||
|
||||
virtual ~btCPUSoftBodySolver();
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
virtual btSoftBodyVertexData &getVertexData();
|
||||
|
||||
virtual btSoftBodyTriangleData &getTriangleData();
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Add a collision object to be used by the indicated softbody.
|
||||
*/
|
||||
virtual void addCollisionObjectForSoftBody( int clothIdentifier, btCollisionObject *collisionObject );
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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 );
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_CPU_SOLVER_H
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer ApplyForcesCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float solverdt;
|
||||
float epsilon;
|
||||
int padding3;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexNormal : register( t1 );
|
||||
StructuredBuffer<float> g_vertexArea : register( t2 );
|
||||
StructuredBuffer<float> g_vertexInverseMass : register( t3 );
|
||||
// TODO: These could be combined into a lift/drag factor array along with medium density
|
||||
StructuredBuffer<float> g_clothLiftFactor : register( t4 );
|
||||
StructuredBuffer<float> g_clothDragFactor : register( t5 );
|
||||
StructuredBuffer<float4> g_clothWindVelocity : register( t6 );
|
||||
StructuredBuffer<float4> g_clothAcceleration : register( t7 );
|
||||
StructuredBuffer<float> g_clothMediumDensity : register( t8 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexForceAccumulator : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u1 );
|
||||
|
||||
float3 projectOnAxis( float3 v, float3 a )
|
||||
{
|
||||
return (a*dot(v, a));
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
ApplyForcesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
unsigned int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothId = g_vertexClothIdentifier[nodeID];
|
||||
float nodeIM = g_vertexInverseMass[nodeID];
|
||||
|
||||
if( nodeIM > 0.0f )
|
||||
{
|
||||
float3 nodeV = g_vertexVelocity[nodeID].xyz;
|
||||
float3 normal = g_vertexNormal[nodeID].xyz;
|
||||
float area = g_vertexArea[nodeID];
|
||||
float3 nodeF = g_vertexForceAccumulator[nodeID].xyz;
|
||||
|
||||
// Read per-cloth values
|
||||
float3 clothAcceleration = g_clothAcceleration[clothId].xyz;
|
||||
float3 clothWindVelocity = g_clothWindVelocity[clothId].xyz;
|
||||
float liftFactor = g_clothLiftFactor[clothId];
|
||||
float dragFactor = g_clothDragFactor[clothId];
|
||||
float mediumDensity = g_clothMediumDensity[clothId];
|
||||
|
||||
// Apply the acceleration to the cloth rather than do this via a force
|
||||
nodeV += (clothAcceleration*solverdt);
|
||||
|
||||
g_vertexVelocity[nodeID] = float4(nodeV, 0.f);
|
||||
|
||||
float3 relativeWindVelocity = nodeV - clothWindVelocity;
|
||||
float relativeSpeedSquared = dot(relativeWindVelocity, relativeWindVelocity);
|
||||
|
||||
if( relativeSpeedSquared > epsilon )
|
||||
{
|
||||
// Correct direction of normal relative to wind direction and get dot product
|
||||
normal = normal * (dot(normal, relativeWindVelocity) < 0 ? -1.f : 1.f);
|
||||
float dvNormal = dot(normal, relativeWindVelocity);
|
||||
if( dvNormal > 0 )
|
||||
{
|
||||
float3 force = float3(0.f, 0.f, 0.f);
|
||||
float c0 = area * dvNormal * relativeSpeedSquared / 2.f;
|
||||
float c1 = c0 * mediumDensity;
|
||||
force += normal * (-c1 * liftFactor);
|
||||
force += normalize(relativeWindVelocity)*(-c1 * dragFactor);
|
||||
|
||||
float dtim = solverdt * nodeIM;
|
||||
float3 forceDTIM = force * dtim;
|
||||
|
||||
float3 nodeFPlusForce = nodeF + force;
|
||||
|
||||
// m_nodesf[i] -= ProjectOnAxis(m_nodesv[i], force.normalized())/dtim;
|
||||
float3 nodeFMinus = nodeF - (projectOnAxis(nodeV, normalize(force))/dtim);
|
||||
|
||||
nodeF = nodeFPlusForce;
|
||||
if( dot(forceDTIM, forceDTIM) > dot(nodeV, nodeV) )
|
||||
nodeF = nodeFMinus;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = float4(nodeF, 0.0f);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer ComputeBoundsCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
int numSoftBodies;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t1 );
|
||||
|
||||
RWStructuredBuffer<uint4> g_clothMinBounds : register( u0 );
|
||||
RWStructuredBuffer<uint4> g_clothMaxBounds : register( u1 );
|
||||
|
||||
groupshared uint4 clothMinBounds[256];
|
||||
groupshared uint4 clothMaxBounds[256];
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
ComputeBoundsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
const unsigned int UINT_MAX = 0xffffffff;
|
||||
|
||||
// Init min and max bounds arrays
|
||||
if( GTid.x < numSoftBodies )
|
||||
{
|
||||
clothMinBounds[GTid.x] = uint4(UINT_MAX, UINT_MAX, UINT_MAX, UINT_MAX);
|
||||
clothMaxBounds[GTid.x] = uint4(0,0,0,0);
|
||||
}
|
||||
|
||||
AllMemoryBarrierWithGroupSync();
|
||||
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
if( clothIdentifier >= 0 )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
|
||||
// Reinterpret position as uint
|
||||
uint3 positionUInt = uint3(asuint(position.x), asuint(position.y), asuint(position.z));
|
||||
|
||||
// Invert sign bit of positives and whole of negatives to allow comparison as unsigned ints
|
||||
//positionUInt.x ^= uint((-int(positionUInt.x >> 31) | 0x80000000));
|
||||
//positionUInt.y ^= uint((-int(positionUInt.y >> 31) | 0x80000000));
|
||||
//positionUInt.z ^= uint((-int(positionUInt.z >> 31) | 0x80000000));
|
||||
positionUInt.x ^= (1+~(positionUInt.x >> 31) | 0x80000000);
|
||||
positionUInt.y ^= (1+~(positionUInt.y >> 31) | 0x80000000);
|
||||
positionUInt.z ^= (1+~(positionUInt.z >> 31) | 0x80000000);
|
||||
|
||||
// Min/max with the LDS values
|
||||
InterlockedMin(clothMinBounds[clothIdentifier].x, positionUInt.x);
|
||||
InterlockedMin(clothMinBounds[clothIdentifier].y, positionUInt.y);
|
||||
InterlockedMin(clothMinBounds[clothIdentifier].z, positionUInt.z);
|
||||
|
||||
InterlockedMax(clothMaxBounds[clothIdentifier].x, positionUInt.x);
|
||||
InterlockedMax(clothMaxBounds[clothIdentifier].y, positionUInt.y);
|
||||
InterlockedMax(clothMaxBounds[clothIdentifier].z, positionUInt.z);
|
||||
}
|
||||
}
|
||||
|
||||
AllMemoryBarrierWithGroupSync();
|
||||
|
||||
|
||||
// Use global atomics to update the global versions of the data
|
||||
if( GTid.x < numSoftBodies )
|
||||
{
|
||||
InterlockedMin(g_clothMinBounds[GTid.x].x, clothMinBounds[GTid.x].x);
|
||||
InterlockedMin(g_clothMinBounds[GTid.x].y, clothMinBounds[GTid.x].y);
|
||||
InterlockedMin(g_clothMinBounds[GTid.x].z, clothMinBounds[GTid.x].z);
|
||||
|
||||
InterlockedMax(g_clothMaxBounds[GTid.x].x, clothMaxBounds[GTid.x].x);
|
||||
InterlockedMax(g_clothMaxBounds[GTid.x].y, clothMaxBounds[GTid.x].y);
|
||||
InterlockedMax(g_clothMaxBounds[GTid.x].z, clothMaxBounds[GTid.x].z);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer IntegrateCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float solverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<float> g_vertexInverseMasses : register( t0 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u1 );
|
||||
RWStructuredBuffer<float4> g_vertexPreviousPositions : register( u2 );
|
||||
RWStructuredBuffer<float4> g_vertexForceAccumulator : register( u3 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
IntegrateKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocity[nodeID].xyz;
|
||||
float3 force = g_vertexForceAccumulator[nodeID].xyz;
|
||||
float inverseMass = g_vertexInverseMasses[nodeID];
|
||||
|
||||
g_vertexPreviousPositions[nodeID] = float4(position, 0.f);
|
||||
velocity += force * inverseMass * solverdt;
|
||||
position += velocity * solverdt;
|
||||
|
||||
g_vertexForceAccumulator[nodeID] = float4(0.f, 0.f, 0.f, 0.0f);
|
||||
g_vertexPositions[nodeID] = float4(position, 0.f);
|
||||
g_vertexVelocity[nodeID] = float4(velocity, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer OutputToVertexArrayCB : register( b0 )
|
||||
{
|
||||
int startNode;
|
||||
int numNodes;
|
||||
int positionOffset;
|
||||
int positionStride;
|
||||
|
||||
int normalOffset;
|
||||
int normalStride;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexNormals : register( t1 );
|
||||
|
||||
RWBuffer<float> g_vertexBuffer : register( u0 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
OutputToVertexArrayWithNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
float4 normal = g_vertexNormals[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
|
||||
int normalDestination = nodeID * normalStride + normalOffset;
|
||||
g_vertexBuffer[normalDestination] = normal.x;
|
||||
g_vertexBuffer[normalDestination+1] = normal.y;
|
||||
g_vertexBuffer[normalDestination+2] = normal.z;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
OutputToVertexArrayWithoutNormalsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float4 position = g_vertexPositions[nodeID + startNode];
|
||||
float4 normal = g_vertexNormals[nodeID + startNode];
|
||||
|
||||
// Stride should account for the float->float4 conversion
|
||||
int positionDestination = nodeID * positionStride + positionOffset;
|
||||
g_vertexBuffer[positionDestination] = position.x;
|
||||
g_vertexBuffer[positionDestination+1] = position.y;
|
||||
g_vertexBuffer[positionDestination+2] = position.z;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer PrepareLinksCB : register( b0 )
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
StructuredBuffer<float> g_linksMassLSC : register( t1 );
|
||||
StructuredBuffer<float4> g_nodesPreviousPosition : register( t2 );
|
||||
|
||||
RWStructuredBuffer<float> g_linksLengthRatio : register( u0 );
|
||||
RWStructuredBuffer<float4> g_linksCurrentLength : register( u1 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
PrepareLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x;
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float4 nodePreviousPosition0 = g_nodesPreviousPosition[node0];
|
||||
float4 nodePreviousPosition1 = g_nodesPreviousPosition[node1];
|
||||
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
|
||||
float4 linkCurrentLength = nodePreviousPosition1 - nodePreviousPosition0;
|
||||
|
||||
float linkLengthRatio = dot(linkCurrentLength, linkCurrentLength)*massLSC;
|
||||
linkLengthRatio = 1./linkLengthRatio;
|
||||
|
||||
g_linksCurrentLength[linkID] = linkCurrentLength;
|
||||
g_linksLengthRatio[linkID] = linkLengthRatio;
|
||||
}
|
||||
}
|
||||
);
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer SolvePositionsFromLinksKernelCB : register( b0 )
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
float ti;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
|
||||
StructuredBuffer<float> g_linksMassLSC : register( t1 );
|
||||
StructuredBuffer<float> g_linksRestLengthSquared : register( t2 );
|
||||
StructuredBuffer<float> g_verticesInverseMass : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u0 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
SolvePositionsFromLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x + startLink;
|
||||
if( DTid.x < numLinks )
|
||||
{
|
||||
float massLSC = g_linksMassLSC[linkID];
|
||||
float restLengthSquared = g_linksRestLengthSquared[linkID];
|
||||
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
|
||||
float inverseMass0 = g_verticesInverseMass[node0];
|
||||
float inverseMass1 = g_verticesInverseMass[node1];
|
||||
|
||||
float3 del = position1 - position0;
|
||||
float len = dot(del, del);
|
||||
float k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
g_vertexPositions[node0] = float4(position0, 0.f);
|
||||
g_vertexPositions[node1] = float4(position1, 0.f);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer SolvePositionsFromLinksKernelCB : register( b0 )
|
||||
{
|
||||
int startWaveInBatch;
|
||||
int numWaves;
|
||||
float kst;
|
||||
float ti;
|
||||
};
|
||||
|
||||
|
||||
// Number of batches per wavefront stored one element per logical wavefront
|
||||
StructuredBuffer<int2> g_wavefrontBatchCountsVertexCounts : register( t0 );
|
||||
// Set of up to maxNumVertices vertex addresses per wavefront
|
||||
StructuredBuffer<int> g_vertexAddressesPerWavefront : register( t1 );
|
||||
|
||||
StructuredBuffer<float> g_verticesInverseMass : register( t2 );
|
||||
|
||||
// Per-link data layed out structured in terms of sub batches within wavefronts
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t3 );
|
||||
StructuredBuffer<float> g_linksMassLSC : register( t4 );
|
||||
StructuredBuffer<float> g_linksRestLengthSquared : register( t5 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u0 );
|
||||
|
||||
// Data loaded on a per-wave basis
|
||||
groupshared int2 wavefrontBatchCountsVertexCounts[WAVEFRONT_BLOCK_MULTIPLIER];
|
||||
groupshared float4 vertexPositionSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER];
|
||||
groupshared float vertexInverseMassSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER];
|
||||
|
||||
// Storing the vertex addresses actually slowed things down a little
|
||||
//groupshared int vertexAddressSharedData[MAX_NUM_VERTICES_PER_WAVE*WAVEFRONT_BLOCK_MULTIPLIER];
|
||||
|
||||
|
||||
[numthreads(BLOCK_SIZE, 1, 1)]
|
||||
void
|
||||
SolvePositionsFromLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
const int laneInWavefront = (DTid.x & (WAVEFRONT_SIZE-1));
|
||||
const int wavefront = startWaveInBatch + (DTid.x / WAVEFRONT_SIZE);
|
||||
const int firstWavefrontInBlock = startWaveInBatch + Gid.x * WAVEFRONT_BLOCK_MULTIPLIER;
|
||||
const int localWavefront = wavefront - firstWavefrontInBlock;
|
||||
|
||||
// Mask out in case there's a stray "wavefront" at the end that's been forced in through the multiplier
|
||||
if( wavefront < (startWaveInBatch + numWaves) )
|
||||
{
|
||||
|
||||
// Load the batch counts for the wavefronts
|
||||
// Mask out in case there's a stray "wavefront" at the end that's been forced in through the multiplier
|
||||
if( laneInWavefront == 0 )
|
||||
{
|
||||
int2 batchesAndVertexCountsWithinWavefront = g_wavefrontBatchCountsVertexCounts[firstWavefrontInBlock + localWavefront];
|
||||
wavefrontBatchCountsVertexCounts[localWavefront] = batchesAndVertexCountsWithinWavefront;
|
||||
}
|
||||
|
||||
|
||||
int2 batchesAndVerticesWithinWavefront = wavefrontBatchCountsVertexCounts[localWavefront];
|
||||
int batchesWithinWavefront = batchesAndVerticesWithinWavefront.x;
|
||||
int verticesUsedByWave = batchesAndVerticesWithinWavefront.y;
|
||||
|
||||
// Load the vertices for the wavefronts
|
||||
for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE )
|
||||
{
|
||||
int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex];
|
||||
|
||||
//vertexAddressSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = vertexAddress;
|
||||
vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_vertexPositions[vertexAddress];
|
||||
vertexInverseMassSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex] = g_verticesInverseMass[vertexAddress];
|
||||
}
|
||||
|
||||
// Ensure compiler does not re-order memory operations
|
||||
AllMemoryBarrier();
|
||||
|
||||
|
||||
// Loop through the batches performing the solve on each in LDS
|
||||
int baseDataLocationForWave = WAVEFRONT_SIZE * wavefront * MAX_BATCHES_PER_WAVE;
|
||||
|
||||
//for( int batch = 0; batch < batchesWithinWavefront; ++batch )
|
||||
|
||||
int batch = 0;
|
||||
do
|
||||
{
|
||||
int baseDataLocation = baseDataLocationForWave + WAVEFRONT_SIZE * batch;
|
||||
int locationOfValue = baseDataLocation + laneInWavefront;
|
||||
|
||||
|
||||
// These loads should all be perfectly linear across the WF
|
||||
int2 localVertexIndices = g_linksVertexIndices[locationOfValue];
|
||||
float massLSC = g_linksMassLSC[locationOfValue];
|
||||
float restLengthSquared = g_linksRestLengthSquared[locationOfValue];
|
||||
|
||||
|
||||
// LDS vertex addresses based on logical wavefront number in block and loaded index
|
||||
int vertexAddress0 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.x;
|
||||
int vertexAddress1 = MAX_NUM_VERTICES_PER_WAVE * localWavefront + localVertexIndices.y;
|
||||
|
||||
float3 position0 = vertexPositionSharedData[vertexAddress0].xyz;
|
||||
float3 position1 = vertexPositionSharedData[vertexAddress1].xyz;
|
||||
|
||||
float inverseMass0 = vertexInverseMassSharedData[vertexAddress0];
|
||||
float inverseMass1 = vertexInverseMassSharedData[vertexAddress1];
|
||||
|
||||
float3 del = position1 - position0;
|
||||
float len = dot(del, del);
|
||||
|
||||
float k = 0;
|
||||
if( massLSC > 0.0f )
|
||||
{
|
||||
k = ((restLengthSquared - len)/(massLSC*(restLengthSquared+len)))*kst;
|
||||
}
|
||||
|
||||
position0 = position0 - del*(k*inverseMass0);
|
||||
position1 = position1 + del*(k*inverseMass1);
|
||||
|
||||
// Ensure compiler does not re-order memory operations
|
||||
AllMemoryBarrier();
|
||||
|
||||
vertexPositionSharedData[vertexAddress0] = float4(position0, 0.f);
|
||||
vertexPositionSharedData[vertexAddress1] = float4(position1, 0.f);
|
||||
|
||||
// Ensure compiler does not re-order memory operations
|
||||
AllMemoryBarrier();
|
||||
|
||||
|
||||
++batch;
|
||||
} while( batch < batchesWithinWavefront );
|
||||
|
||||
// Update the global memory vertices for the wavefronts
|
||||
for( int vertex = laneInWavefront; vertex < verticesUsedByWave; vertex+=WAVEFRONT_SIZE )
|
||||
{
|
||||
int vertexAddress = g_vertexAddressesPerWavefront[wavefront*MAX_NUM_VERTICES_PER_WAVE + vertex];
|
||||
|
||||
g_vertexPositions[vertexAddress] = vertexPositionSharedData[localWavefront*MAX_NUM_VERTICES_PER_WAVE + vertex];
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateConstantsCB : register( b0 )
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t1 );
|
||||
StructuredBuffer<float> g_vertexInverseMasses : register( t2 );
|
||||
StructuredBuffer<float> g_linksMaterialLSC : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float> g_linksMassLSC : register( u0 );
|
||||
RWStructuredBuffer<float> g_linksRestLengthSquared : register( u1 );
|
||||
RWStructuredBuffer<float> g_linksRestLengths : register( u2 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdateConstantsKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x;
|
||||
if( linkID < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
float linearStiffnessCoefficient = g_linksMaterialLSC[ linkID ];
|
||||
|
||||
float3 position0 = g_vertexPositions[node0].xyz;
|
||||
float3 position1 = g_vertexPositions[node1].xyz;
|
||||
float inverseMass0 = g_vertexInverseMasses[node0];
|
||||
float inverseMass1 = g_vertexInverseMasses[node1];
|
||||
|
||||
float3 difference = position0 - position1;
|
||||
float length2 = dot(difference, difference);
|
||||
float length = sqrt(length2);
|
||||
|
||||
g_linksRestLengths[linkID] = length;
|
||||
g_linksMassLSC[linkID] = (inverseMass0 + inverseMass1)/linearStiffnessCoefficient;
|
||||
g_linksRestLengthSquared[linkID] = length*length;
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateVelocitiesFromPositionsWithVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexClothIndices : register( t2 );
|
||||
StructuredBuffer<float> g_clothVelocityCorrectionCoefficients : register( t3 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t4 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
updateVelocitiesFromPositionsWithVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float velocityCorrectionCoefficient = g_clothVelocityCorrectionCoefficients[clothIndex];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity += difference*velocityCorrectionCoefficient*isolverdt;
|
||||
|
||||
// Damp the velocity
|
||||
velocity *= velocityCoefficient;
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateSoftBodiesCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
unsigned int startFace;
|
||||
unsigned int numFaces;
|
||||
float epsilon;
|
||||
};
|
||||
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int4> g_triangleVertexIndexSet : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexTriangleCount : register( t2 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexNormals : register( u0 );
|
||||
RWStructuredBuffer<float> g_vertexArea : register( u1 );
|
||||
RWStructuredBuffer<float4> g_triangleNormals : register( u2 );
|
||||
RWStructuredBuffer<float> g_triangleArea : register( u3 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
ResetNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
if( DTid.x < numNodes )
|
||||
{
|
||||
g_vertexNormals[DTid.x] = float4(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
g_vertexArea[DTid.x] = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdateSoftBodiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int faceID = DTid.x + startFace;
|
||||
if( DTid.x < numFaces )
|
||||
{
|
||||
int4 triangleIndexSet = g_triangleVertexIndexSet[ faceID ];
|
||||
int nodeIndex0 = triangleIndexSet.x;
|
||||
int nodeIndex1 = triangleIndexSet.y;
|
||||
int nodeIndex2 = triangleIndexSet.z;
|
||||
|
||||
float3 node0 = g_vertexPositions[nodeIndex0].xyz;
|
||||
float3 node1 = g_vertexPositions[nodeIndex1].xyz;
|
||||
float3 node2 = g_vertexPositions[nodeIndex2].xyz;
|
||||
float3 nodeNormal0 = g_vertexNormals[nodeIndex0].xyz;
|
||||
float3 nodeNormal1 = g_vertexNormals[nodeIndex1].xyz;
|
||||
float3 nodeNormal2 = g_vertexNormals[nodeIndex2].xyz;
|
||||
float vertexArea0 = g_vertexArea[nodeIndex0];
|
||||
float vertexArea1 = g_vertexArea[nodeIndex1];
|
||||
float vertexArea2 = g_vertexArea[nodeIndex2];
|
||||
|
||||
float3 vector0 = node1 - node0;
|
||||
float3 vector1 = node2 - node0;
|
||||
|
||||
float3 faceNormal = cross(vector0.xyz, vector1.xyz);
|
||||
float triangleArea = length(faceNormal);
|
||||
|
||||
nodeNormal0 = nodeNormal0 + faceNormal;
|
||||
nodeNormal1 = nodeNormal1 + faceNormal;
|
||||
nodeNormal2 = nodeNormal2 + faceNormal;
|
||||
vertexArea0 = vertexArea0 + triangleArea;
|
||||
vertexArea1 = vertexArea1 + triangleArea;
|
||||
vertexArea2 = vertexArea2 + triangleArea;
|
||||
|
||||
g_triangleNormals[faceID] = float4(normalize(faceNormal), 0.f);
|
||||
g_vertexNormals[nodeIndex0] = float4(nodeNormal0, 0.f);
|
||||
g_vertexNormals[nodeIndex1] = float4(nodeNormal1, 0.f);
|
||||
g_vertexNormals[nodeIndex2] = float4(nodeNormal2, 0.f);
|
||||
g_triangleArea[faceID] = triangleArea;
|
||||
g_vertexArea[nodeIndex0] = vertexArea0;
|
||||
g_vertexArea[nodeIndex1] = vertexArea1;
|
||||
g_vertexArea[nodeIndex2] = vertexArea2;
|
||||
}
|
||||
}
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
NormalizeNormalsAndAreasKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
if( DTid.x < numNodes )
|
||||
{
|
||||
float4 normal = g_vertexNormals[DTid.x];
|
||||
float area = g_vertexArea[DTid.x];
|
||||
int numTriangles = g_vertexTriangleCount[DTid.x];
|
||||
|
||||
float vectorLength = length(normal);
|
||||
|
||||
g_vertexNormals[DTid.x] = normalize(normal);
|
||||
g_vertexArea[DTid.x] = area/float(numTriangles);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdateVelocitiesFromPositionsWithoutVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float isolverdt;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexPositions : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<int> g_vertexClothIndices : register( t2 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
updateVelocitiesFromPositionsWithoutVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
if( nodeID < numNodes )
|
||||
{
|
||||
float3 position = g_vertexPositions[nodeID].xyz;
|
||||
float3 previousPosition = g_vertexPreviousPositions[nodeID].xyz;
|
||||
float3 velocity = g_vertexVelocities[nodeID].xyz;
|
||||
int clothIndex = g_vertexClothIndices[nodeID];
|
||||
float dampingFactor = g_clothDampingFactor[clothIndex];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
|
||||
float3 difference = position - previousPosition;
|
||||
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
g_vertexForces[nodeID] = float4(0.f, 0.f, 0.f, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer UpdatePositionsFromVelocitiesCB : register( b0 )
|
||||
{
|
||||
int numNodes;
|
||||
float solverSDT;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
|
||||
StructuredBuffer<float4> g_vertexVelocities : register( t0 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexPreviousPositions : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexCurrentPosition : register( u1 );
|
||||
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
UpdatePositionsFromVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int vertexID = DTid.x;
|
||||
if( vertexID < numNodes )
|
||||
{
|
||||
float3 previousPosition = g_vertexPreviousPositions[vertexID].xyz;
|
||||
float3 velocity = g_vertexVelocities[vertexID].xyz;
|
||||
|
||||
float3 newPosition = previousPosition + velocity*solverSDT;
|
||||
|
||||
g_vertexCurrentPosition[vertexID] = float4(newPosition, 0.f);
|
||||
g_vertexPreviousPositions[vertexID] = float4(newPosition, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer VSolveLinksCB : register( b0 )
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
int padding;
|
||||
};
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int2> g_linksVertexIndices : register( t0 );
|
||||
|
||||
StructuredBuffer<float> g_linksLengthRatio : register( t1 );
|
||||
StructuredBuffer<float4> g_linksCurrentLength : register( t2 );
|
||||
StructuredBuffer<float> g_vertexInverseMass : register( t3 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexVelocity : register( u0 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
VSolveLinksKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int linkID = DTid.x + startLink;
|
||||
if( DTid.x < numLinks )
|
||||
{
|
||||
int2 nodeIndices = g_linksVertexIndices[linkID];
|
||||
int node0 = nodeIndices.x;
|
||||
int node1 = nodeIndices.y;
|
||||
|
||||
float linkLengthRatio = g_linksLengthRatio[linkID];
|
||||
float3 linkCurrentLength = g_linksCurrentLength[linkID].xyz;
|
||||
|
||||
float3 vertexVelocity0 = g_vertexVelocity[node0].xyz;
|
||||
float3 vertexVelocity1 = g_vertexVelocity[node1].xyz;
|
||||
|
||||
float vertexInverseMass0 = g_vertexInverseMass[node0];
|
||||
float vertexInverseMass1 = g_vertexInverseMass[node1];
|
||||
|
||||
float3 nodeDifference = vertexVelocity0 - vertexVelocity1;
|
||||
float dotResult = dot(linkCurrentLength, nodeDifference);
|
||||
float j = -dotResult*linkLengthRatio*kst;
|
||||
|
||||
float3 velocityChange0 = linkCurrentLength*(j*vertexInverseMass0);
|
||||
float3 velocityChange1 = linkCurrentLength*(j*vertexInverseMass1);
|
||||
|
||||
vertexVelocity0 += velocityChange0;
|
||||
vertexVelocity1 -= velocityChange1;
|
||||
|
||||
g_vertexVelocity[node0] = float4(vertexVelocity0, 0.f);
|
||||
g_vertexVelocity[node1] = float4(vertexVelocity1, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,170 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer SolvePositionsFromLinksKernelCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float isolverdt;
|
||||
int padding0;
|
||||
int padding1;
|
||||
};
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
float4x4 shapeTransform;
|
||||
float4 linearVelocity;
|
||||
float4 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
|
||||
// Shape information
|
||||
// Compressed from the union
|
||||
float radius;
|
||||
float halfHeight;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
int padding0;
|
||||
int padding1;
|
||||
|
||||
};
|
||||
|
||||
// From btBroadphaseProxy.h
|
||||
static const int CAPSULE_SHAPE_PROXYTYPE = 10;
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<float> g_perClothFriction : register( t2 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t3 );
|
||||
StructuredBuffer<CollisionObjectIndices> g_perClothCollisionObjectIndices : register( t4 );
|
||||
StructuredBuffer<CollisionShapeDescription> g_collisionObjectDetails : register( t5 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u1 );
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u2 );
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
SolveCollisionsAndUpdateVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
float3 forceOnVertex = float3(0.f, 0.f, 0.f);
|
||||
if( DTid.x < numNodes )
|
||||
{
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
float4 position = float4(g_vertexPositions[nodeID].xyz, 1.f);
|
||||
float4 previousPosition = float4(g_vertexPreviousPositions[nodeID].xyz, 1.f);
|
||||
float3 velocity;
|
||||
float clothFriction = g_perClothFriction[clothIdentifier];
|
||||
float dampingFactor = g_clothDampingFactor[clothIdentifier];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
|
||||
|
||||
if( collisionObjectIndices.firstObject != collisionObjectIndices.endObject )
|
||||
{
|
||||
velocity = float3(15, 0, 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;
|
||||
float4x4 worldTransform = shapeDescription.shapeTransform;
|
||||
|
||||
float4 c1 = float4(0.f, -capsuleHalfHeight, 0.f, 1.f);
|
||||
float4 c2 = float4(0.f, +capsuleHalfHeight, 0.f, 1.f);
|
||||
float4 worldC1 = mul(worldTransform, c1);
|
||||
float4 worldC2 = mul(worldTransform, c2);
|
||||
float3 segment = (worldC2 - worldC1).xyz;
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( dot( (worldC1 - position).xyz, segment ) / dot(segment, segment) );
|
||||
|
||||
float4 closestPoint = (worldC1 + float4(segment * distanceAlongSegment, 0.f));
|
||||
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;
|
||||
float3 normalVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
dist = distanceFromC1;
|
||||
normalVector = normalize(position - worldC1).xyz;
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
dist = distanceFromC2;
|
||||
normalVector = normalize(position - worldC2).xyz;
|
||||
} else {
|
||||
dist = distanceFromLine;
|
||||
normalVector = normalize(position - closestPoint).xyz;
|
||||
}
|
||||
|
||||
float3 colliderLinearVelocity = shapeDescription.linearVelocity.xyz;
|
||||
float3 colliderAngularVelocity = shapeDescription.angularVelocity.xyz;
|
||||
float3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position.xyz - worldTransform._m03_m13_m23);
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
|
||||
// In case of no collision, this is the value of velocity
|
||||
velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
|
||||
|
||||
|
||||
// Check for a collision
|
||||
if( dist < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
position = position + float4((minDistance - dist)*normalVector*0.9, 0.f);
|
||||
velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
|
||||
float3 relativeVelocity = velocity - velocityOfSurfacePoint;
|
||||
|
||||
float3 p1 = normalize(cross(normalVector, segment));
|
||||
float3 p2 = normalize(cross(p1, normalVector));
|
||||
// Full friction is sum of velocities in each direction of plane
|
||||
float3 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);
|
||||
|
||||
if( approachSpeed <= 0.0 )
|
||||
forceOnVertex -= frictionVector;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Update velocity
|
||||
float3 difference = position.xyz - previousPosition.xyz;
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
}
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
|
||||
// Update external force
|
||||
g_vertexForces[nodeID] = float4(forceOnVertex, 0.f);
|
||||
|
||||
g_vertexPositions[nodeID] = float4(position.xyz, 0.f);
|
||||
}
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,191 @@
|
|||
MSTRINGIFY(
|
||||
|
||||
cbuffer SolvePositionsFromLinksKernelCB : register( b0 )
|
||||
{
|
||||
unsigned int numNodes;
|
||||
float isolverdt;
|
||||
int padding0;
|
||||
int padding1;
|
||||
};
|
||||
|
||||
struct CollisionObjectIndices
|
||||
{
|
||||
int firstObject;
|
||||
int endObject;
|
||||
};
|
||||
|
||||
struct CollisionShapeDescription
|
||||
{
|
||||
float4x4 shapeTransform;
|
||||
float4 linearVelocity;
|
||||
float4 angularVelocity;
|
||||
|
||||
int softBodyIdentifier;
|
||||
int collisionShapeType;
|
||||
|
||||
|
||||
// Shape information
|
||||
// Compressed from the union
|
||||
float radius;
|
||||
float halfHeight;
|
||||
|
||||
float margin;
|
||||
float friction;
|
||||
|
||||
int padding0;
|
||||
int padding1;
|
||||
|
||||
};
|
||||
|
||||
// From btBroadphaseProxy.h
|
||||
static const int CAPSULE_SHAPE_PROXYTYPE = 10;
|
||||
|
||||
// Node indices for each link
|
||||
StructuredBuffer<int> g_vertexClothIdentifier : register( t0 );
|
||||
StructuredBuffer<float4> g_vertexPreviousPositions : register( t1 );
|
||||
StructuredBuffer<float> g_perClothFriction : register( t2 );
|
||||
StructuredBuffer<float> g_clothDampingFactor : register( t3 );
|
||||
StructuredBuffer<CollisionObjectIndices> g_perClothCollisionObjectIndices : register( t4 );
|
||||
StructuredBuffer<CollisionShapeDescription> g_collisionObjectDetails : register( t5 );
|
||||
|
||||
RWStructuredBuffer<float4> g_vertexForces : register( u0 );
|
||||
RWStructuredBuffer<float4> g_vertexVelocities : register( u1 );
|
||||
RWStructuredBuffer<float4> g_vertexPositions : register( u2 );
|
||||
|
||||
// A buffer of local collision shapes
|
||||
// TODO: Iterate to support more than 16
|
||||
groupshared CollisionShapeDescription localCollisionShapes[16];
|
||||
|
||||
[numthreads(128, 1, 1)]
|
||||
void
|
||||
SolveCollisionsAndUpdateVelocitiesKernel( uint3 Gid : SV_GroupID, uint3 DTid : SV_DispatchThreadID, uint3 GTid : SV_GroupThreadID, uint GI : SV_GroupIndex )
|
||||
{
|
||||
int nodeID = DTid.x;
|
||||
float3 forceOnVertex = float3(0.f, 0.f, 0.f);
|
||||
|
||||
int clothIdentifier = g_vertexClothIdentifier[nodeID];
|
||||
float4 position = float4(g_vertexPositions[nodeID].xyz, 1.f);
|
||||
float4 previousPosition = float4(g_vertexPreviousPositions[nodeID].xyz, 1.f);
|
||||
float3 velocity;
|
||||
float clothFriction = g_perClothFriction[clothIdentifier];
|
||||
float dampingFactor = g_clothDampingFactor[clothIdentifier];
|
||||
float velocityCoefficient = (1.f - dampingFactor);
|
||||
CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
|
||||
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
// We have some possible collisions to deal with
|
||||
|
||||
// First load all of the collision objects into LDS
|
||||
int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
|
||||
if( GTid.x < numObjects )
|
||||
{
|
||||
localCollisionShapes[GTid.x] = g_collisionObjectDetails[ collisionObjectIndices.firstObject + GTid.x ];
|
||||
}
|
||||
}
|
||||
|
||||
// Safe as the vertices are padded so that not more than one soft body is in a group
|
||||
AllMemoryBarrierWithGroupSync();
|
||||
|
||||
// Annoyingly, even though I know the flow control is not varying, the compiler will not let me skip this
|
||||
if( numObjects > 0 )
|
||||
{
|
||||
velocity = float3(0, 0, 0);
|
||||
|
||||
|
||||
// We have some possible collisions to deal with
|
||||
for( int collision = 0; collision < numObjects; ++collision )
|
||||
{
|
||||
CollisionShapeDescription shapeDescription = localCollisionShapes[collision];
|
||||
float colliderFriction = shapeDescription.friction;
|
||||
|
||||
if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
|
||||
{
|
||||
// Colliding with a capsule
|
||||
|
||||
float capsuleHalfHeight = localCollisionShapes[collision].halfHeight;
|
||||
float capsuleRadius = localCollisionShapes[collision].radius;
|
||||
float capsuleMargin = localCollisionShapes[collision].margin;
|
||||
|
||||
float4x4 worldTransform = localCollisionShapes[collision].shapeTransform;
|
||||
|
||||
float4 c1 = float4(0.f, -capsuleHalfHeight, 0.f, 1.f);
|
||||
float4 c2 = float4(0.f, +capsuleHalfHeight, 0.f, 1.f);
|
||||
float4 worldC1 = mul(worldTransform, c1);
|
||||
float4 worldC2 = mul(worldTransform, c2);
|
||||
float3 segment = (worldC2 - worldC1).xyz;
|
||||
|
||||
// compute distance of tangent to vertex along line segment in capsule
|
||||
float distanceAlongSegment = -( dot( (worldC1 - position).xyz, segment ) / dot(segment, segment) );
|
||||
|
||||
float4 closestPoint = (worldC1 + float4(segment * distanceAlongSegment, 0.f));
|
||||
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;
|
||||
float3 normalVector;
|
||||
if( distanceAlongSegment < 0 )
|
||||
{
|
||||
dist = distanceFromC1;
|
||||
normalVector = normalize(position - worldC1).xyz;
|
||||
} else if( distanceAlongSegment > 1.f ) {
|
||||
dist = distanceFromC2;
|
||||
normalVector = normalize(position - worldC2).xyz;
|
||||
} else {
|
||||
dist = distanceFromLine;
|
||||
normalVector = normalize(position - closestPoint).xyz;
|
||||
}
|
||||
|
||||
float3 colliderLinearVelocity = localCollisionShapes[collision].linearVelocity.xyz;
|
||||
float3 colliderAngularVelocity = localCollisionShapes[collision].angularVelocity.xyz;
|
||||
float3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position.xyz - worldTransform._m03_m13_m23);
|
||||
|
||||
float minDistance = capsuleRadius + capsuleMargin;
|
||||
|
||||
// In case of no collision, this is the value of velocity
|
||||
velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
|
||||
|
||||
|
||||
// Check for a collision
|
||||
if( dist < minDistance )
|
||||
{
|
||||
// Project back to surface along normal
|
||||
position = position + float4((minDistance - dist)*normalVector*0.9, 0.f);
|
||||
velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
|
||||
float3 relativeVelocity = velocity - velocityOfSurfacePoint;
|
||||
|
||||
float3 p1 = normalize(cross(normalVector, segment));
|
||||
float3 p2 = normalize(cross(p1, normalVector));
|
||||
// Full friction is sum of velocities in each direction of plane
|
||||
float3 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);
|
||||
|
||||
if( approachSpeed <= 0.0 )
|
||||
forceOnVertex -= frictionVector;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// Update velocity
|
||||
float3 difference = position.xyz - previousPosition.xyz;
|
||||
velocity = difference*velocityCoefficient*isolverdt;
|
||||
}
|
||||
|
||||
g_vertexVelocities[nodeID] = float4(velocity, 0.f);
|
||||
|
||||
// Update external force
|
||||
g_vertexForces[nodeID] = float4(forceOnVertex, 0.f);
|
||||
|
||||
g_vertexPositions[nodeID] = float4(position.xyz, 0.f);
|
||||
}
|
||||
|
||||
);
|
||||
|
|
@ -0,0 +1,309 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
|
||||
// DX11 support
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
/**
|
||||
* DX11 Buffer that tracks a host buffer on use to ensure size-correctness.
|
||||
*/
|
||||
template <typename ElementType> class btDX11Buffer
|
||||
{
|
||||
protected:
|
||||
ID3D11Device* m_d3dDevice;
|
||||
ID3D11DeviceContext* m_d3dDeviceContext;
|
||||
|
||||
ID3D11Buffer* m_Buffer;
|
||||
ID3D11ShaderResourceView* m_SRV;
|
||||
ID3D11UnorderedAccessView* m_UAV;
|
||||
btAlignedObjectArray< ElementType >* m_CPUBuffer;
|
||||
|
||||
// TODO: Separate this from the main class
|
||||
// as read back buffers can be shared between buffers
|
||||
ID3D11Buffer* m_readBackBuffer;
|
||||
|
||||
int m_gpuSize;
|
||||
bool m_onGPU;
|
||||
|
||||
bool m_readOnlyOnGPU;
|
||||
|
||||
bool createBuffer( ID3D11Buffer *preexistingBuffer = 0)
|
||||
{
|
||||
HRESULT hr = S_OK;
|
||||
|
||||
// Create all CS buffers
|
||||
if( preexistingBuffer )
|
||||
{
|
||||
m_Buffer = preexistingBuffer;
|
||||
} else {
|
||||
D3D11_BUFFER_DESC buffer_desc;
|
||||
ZeroMemory(&buffer_desc, sizeof(buffer_desc));
|
||||
buffer_desc.Usage = D3D11_USAGE_DEFAULT;
|
||||
if( m_readOnlyOnGPU )
|
||||
buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE;
|
||||
else
|
||||
buffer_desc.BindFlags = D3D11_BIND_SHADER_RESOURCE | D3D11_BIND_UNORDERED_ACCESS;
|
||||
buffer_desc.MiscFlags = D3D11_RESOURCE_MISC_BUFFER_STRUCTURED;
|
||||
|
||||
buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
buffer_desc.StructureByteStride = sizeof(ElementType);
|
||||
hr = m_d3dDevice->CreateBuffer(&buffer_desc, NULL, &m_Buffer);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
}
|
||||
|
||||
if( m_readOnlyOnGPU )
|
||||
{
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
|
||||
ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
|
||||
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
} else {
|
||||
// Create SRV
|
||||
D3D11_SHADER_RESOURCE_VIEW_DESC srvbuffer_desc;
|
||||
ZeroMemory(&srvbuffer_desc, sizeof(srvbuffer_desc));
|
||||
srvbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
srvbuffer_desc.ViewDimension = D3D11_SRV_DIMENSION_BUFFER;
|
||||
|
||||
srvbuffer_desc.Buffer.ElementWidth = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateShaderResourceView(m_Buffer, &srvbuffer_desc, &m_SRV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
|
||||
// Create UAV
|
||||
D3D11_UNORDERED_ACCESS_VIEW_DESC uavbuffer_desc;
|
||||
ZeroMemory(&uavbuffer_desc, sizeof(uavbuffer_desc));
|
||||
uavbuffer_desc.Format = DXGI_FORMAT_UNKNOWN;
|
||||
uavbuffer_desc.ViewDimension = D3D11_UAV_DIMENSION_BUFFER;
|
||||
|
||||
uavbuffer_desc.Buffer.NumElements = m_CPUBuffer->size();
|
||||
hr = m_d3dDevice->CreateUnorderedAccessView(m_Buffer, &uavbuffer_desc, &m_UAV);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
|
||||
// Create read back buffer
|
||||
D3D11_BUFFER_DESC readback_buffer_desc;
|
||||
ZeroMemory(&readback_buffer_desc, sizeof(readback_buffer_desc));
|
||||
|
||||
readback_buffer_desc.ByteWidth = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
readback_buffer_desc.Usage = D3D11_USAGE_STAGING;
|
||||
readback_buffer_desc.CPUAccessFlags = D3D11_CPU_ACCESS_READ;
|
||||
readback_buffer_desc.StructureByteStride = sizeof(ElementType);
|
||||
hr = m_d3dDevice->CreateBuffer(&readback_buffer_desc, NULL, &m_readBackBuffer);
|
||||
if( FAILED( hr ) )
|
||||
return (hr==S_OK);
|
||||
}
|
||||
|
||||
m_gpuSize = m_CPUBuffer->size();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
public:
|
||||
btDX11Buffer( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext, btAlignedObjectArray< ElementType > *CPUBuffer, bool readOnly )
|
||||
{
|
||||
m_d3dDevice = d3dDevice;
|
||||
m_d3dDeviceContext = d3dDeviceContext;
|
||||
m_Buffer = 0;
|
||||
m_SRV = 0;
|
||||
m_UAV = 0;
|
||||
m_readBackBuffer = 0;
|
||||
|
||||
m_CPUBuffer = CPUBuffer;
|
||||
|
||||
m_gpuSize = 0;
|
||||
m_onGPU = false;
|
||||
|
||||
m_readOnlyOnGPU = readOnly;
|
||||
}
|
||||
|
||||
virtual ~btDX11Buffer()
|
||||
{
|
||||
SAFE_RELEASE(m_Buffer);
|
||||
SAFE_RELEASE(m_SRV);
|
||||
SAFE_RELEASE(m_UAV);
|
||||
SAFE_RELEASE(m_readBackBuffer);
|
||||
}
|
||||
|
||||
ID3D11ShaderResourceView* &getSRV()
|
||||
{
|
||||
return m_SRV;
|
||||
}
|
||||
|
||||
ID3D11UnorderedAccessView* &getUAV()
|
||||
{
|
||||
return m_UAV;
|
||||
}
|
||||
|
||||
ID3D11Buffer* &getBuffer()
|
||||
{
|
||||
return m_Buffer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the data to the GPU if it is not there already.
|
||||
*/
|
||||
bool moveToGPU()
|
||||
{
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
m_onGPU = false;
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
// If the buffer doesn't exist or the CPU-side buffer has changed size, create
|
||||
// We should really delete the old one, too, but let's leave that for later
|
||||
if( !m_Buffer || (m_CPUBuffer->size() != m_gpuSize) )
|
||||
{
|
||||
SAFE_RELEASE(m_Buffer);
|
||||
SAFE_RELEASE(m_SRV);
|
||||
SAFE_RELEASE(m_UAV);
|
||||
SAFE_RELEASE(m_readBackBuffer);
|
||||
if( !createBuffer() )
|
||||
{
|
||||
btAssert("Buffer creation failed.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move the data back from the GPU if it is on there and isn't read only.
|
||||
*/
|
||||
bool moveFromGPU()
|
||||
{
|
||||
if( m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if( m_onGPU && !m_readOnlyOnGPU )
|
||||
{
|
||||
// Copy back
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {0};
|
||||
//m_pd3dImmediateContext->CopyResource(m_phAngVelReadBackBuffer, m_phAngVel);
|
||||
|
||||
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->CopySubresourceRegion(
|
||||
m_readBackBuffer,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0 ,
|
||||
m_Buffer,
|
||||
0,
|
||||
&destRegion
|
||||
);
|
||||
|
||||
m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
|
||||
//memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) ));
|
||||
memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
|
||||
m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
|
||||
|
||||
m_onGPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the data back from the GPU without changing its state to be CPU-side.
|
||||
* Useful if we just want to view it on the host for visualization.
|
||||
*/
|
||||
bool copyFromGPU()
|
||||
{
|
||||
if( m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if( m_onGPU && !m_readOnlyOnGPU )
|
||||
{
|
||||
// Copy back
|
||||
D3D11_MAPPED_SUBRESOURCE MappedResource = {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->CopySubresourceRegion(
|
||||
m_readBackBuffer,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0 ,
|
||||
m_Buffer,
|
||||
0,
|
||||
&destRegion
|
||||
);
|
||||
|
||||
m_d3dDeviceContext->Map(m_readBackBuffer, 0, D3D11_MAP_READ, 0, &MappedResource);
|
||||
//memcpy(m_hAngVel, MappedResource.pData, (m_maxObjs * sizeof(float) ));
|
||||
memcpy(&((*m_CPUBuffer)[0]), MappedResource.pData, ((m_CPUBuffer->size()) * sizeof(ElementType) ));
|
||||
m_d3dDeviceContext->Unmap(m_readBackBuffer, 0);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call if data has changed on the CPU.
|
||||
* Can then trigger a move to the GPU as necessary.
|
||||
*/
|
||||
virtual void changedOnCPU()
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
}; // class btDX11Buffer
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_DX11_H
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
|
||||
class btSoftBodyLinkDataDX11 : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
|
||||
btDX11Buffer<LinkNodePair> m_dx11Links;
|
||||
btDX11Buffer<float> m_dx11LinkStrength;
|
||||
btDX11Buffer<float> m_dx11LinksMassLSC;
|
||||
btDX11Buffer<float> m_dx11LinksRestLengthSquared;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11LinksCLength;
|
||||
btDX11Buffer<float> m_dx11LinksLengthRatio;
|
||||
btDX11Buffer<float> m_dx11LinksRestLength;
|
||||
btDX11Buffer<float> m_dx11LinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
btSoftBodyLinkDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
|
||||
virtual ~btSoftBodyLinkDataDX11();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_DX11_H
|
||||
|
|
@ -0,0 +1,173 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
#ifndef BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H
|
||||
#define BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
|
||||
class btSoftBodyLinkDataDX11SIMDAware : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
const int m_wavefrontSize;
|
||||
const int m_linksPerWorkItem;
|
||||
const int m_maxLinksPerWavefront;
|
||||
int m_maxBatchesWithinWave;
|
||||
int m_maxVerticesWithinWave;
|
||||
int m_numWavefronts;
|
||||
|
||||
int m_maxVertex;
|
||||
|
||||
struct NumBatchesVerticesPair
|
||||
{
|
||||
int numBatches;
|
||||
int numVertices;
|
||||
};
|
||||
|
||||
// Array storing number of links in each wavefront
|
||||
btAlignedObjectArray<int> m_linksPerWavefront;
|
||||
btAlignedObjectArray<NumBatchesVerticesPair> m_numBatchesAndVerticesWithinWaves;
|
||||
btDX11Buffer< NumBatchesVerticesPair > m_dx11NumBatchesAndVerticesWithinWaves;
|
||||
|
||||
// All arrays here will contain batches of m_maxLinksPerWavefront links
|
||||
// ordered by wavefront.
|
||||
// with either global vertex pairs or local vertex pairs
|
||||
btAlignedObjectArray< int > m_wavefrontVerticesGlobalAddresses; // List of global vertices per wavefront
|
||||
btDX11Buffer<int> m_dx11WavefrontVerticesGlobalAddresses;
|
||||
btAlignedObjectArray< LinkNodePair > m_linkVerticesLocalAddresses; // Vertex pair for the link
|
||||
btDX11Buffer<LinkNodePair> m_dx11LinkVerticesLocalAddresses;
|
||||
btDX11Buffer<float> m_dx11LinkStrength;
|
||||
btDX11Buffer<float> m_dx11LinksMassLSC;
|
||||
btDX11Buffer<float> m_dx11LinksRestLengthSquared;
|
||||
btDX11Buffer<float> m_dx11LinksRestLength;
|
||||
btDX11Buffer<float> m_dx11LinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_wavefrontBatchStartLengths;
|
||||
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
btSoftBodyLinkDataDX11SIMDAware( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
|
||||
virtual ~btSoftBodyLinkDataDX11SIMDAware();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
|
||||
int getMaxVerticesPerWavefront()
|
||||
{
|
||||
return m_maxVerticesWithinWave;
|
||||
}
|
||||
|
||||
int getWavefrontSize()
|
||||
{
|
||||
return m_wavefrontSize;
|
||||
}
|
||||
|
||||
int getLinksPerWorkItem()
|
||||
{
|
||||
return m_linksPerWorkItem;
|
||||
}
|
||||
|
||||
int getMaxLinksPerWavefront()
|
||||
{
|
||||
return m_maxLinksPerWavefront;
|
||||
}
|
||||
|
||||
int getMaxBatchesPerWavefront()
|
||||
{
|
||||
return m_maxBatchesWithinWave;
|
||||
}
|
||||
|
||||
int getNumWavefronts()
|
||||
{
|
||||
return m_numWavefronts;
|
||||
}
|
||||
|
||||
NumBatchesVerticesPair getNumBatchesAndVerticesWithinWavefront( int wavefront )
|
||||
{
|
||||
return m_numBatchesAndVerticesWithinWaves[wavefront];
|
||||
}
|
||||
|
||||
int getVertexGlobalAddresses( int vertexIndex )
|
||||
{
|
||||
return m_wavefrontVerticesGlobalAddresses[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post-batching local addresses of the vertex pair for a link assuming all vertices used by a wavefront are loaded locally.
|
||||
*/
|
||||
LinkNodePair getVertexPairLocalAddresses( int linkIndex )
|
||||
{
|
||||
return m_linkVerticesLocalAddresses[linkIndex];
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_LINK_DATA_DX11_SIMDAWARE_H
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class btSoftBodyTriangleDataDX11 : public btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
btDX11Buffer<btSoftBodyTriangleData::TriangleNodeSet> m_dx11VertexIndices;
|
||||
btDX11Buffer<float> m_dx11Area;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11Normal;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_triangleAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
|
||||
virtual ~btSoftBodyTriangleDataDX11();
|
||||
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createTriangles( int numTriangles );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire triangle set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_DX11_H
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <crtdbg.h>
|
||||
#include <d3d11.h>
|
||||
#include <d3dx11.h>
|
||||
#include <d3dcompiler.h>
|
||||
|
||||
class btDX11VertexBufferDescriptor : public btVertexBufferDescriptor
|
||||
{
|
||||
protected:
|
||||
/** Context of the DX11 device on which the vertex buffer is stored. */
|
||||
ID3D11DeviceContext* m_context;
|
||||
/** DX11 vertex buffer */
|
||||
ID3D11Buffer* m_vertexBuffer;
|
||||
/** UAV for DX11 buffer */
|
||||
ID3D11UnorderedAccessView* m_vertexBufferUAV;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* buffer is a pointer to the DX11 buffer to place the vertex data in.
|
||||
* UAV is a pointer to the UAV representation of the buffer laid out in floats.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride )
|
||||
{
|
||||
m_context = context;
|
||||
m_vertexBuffer = buffer;
|
||||
m_vertexBufferUAV = UAV;
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* buffer is a pointer to the DX11 buffer to place the vertex data in.
|
||||
* UAV is a pointer to the UAV representation of the buffer laid out in floats.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
* normalOffset is the offset in floats to the first normal.
|
||||
* normalStride is the stride in floats between normals.
|
||||
*/
|
||||
btDX11VertexBufferDescriptor( ID3D11DeviceContext* context, ID3D11Buffer* buffer, ID3D11UnorderedAccessView *UAV, int vertexOffset, int vertexStride, int normalOffset, int normalStride )
|
||||
{
|
||||
m_context = context;
|
||||
m_vertexBuffer = buffer;
|
||||
m_vertexBufferUAV = UAV;
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
|
||||
m_normalOffset = normalOffset;
|
||||
m_normalStride = normalStride;
|
||||
m_hasNormals = true;
|
||||
}
|
||||
|
||||
virtual ~btDX11VertexBufferDescriptor()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the vertex buffer descriptor.
|
||||
*/
|
||||
virtual BufferTypes getBufferType() const
|
||||
{
|
||||
return DX11_BUFFER;
|
||||
}
|
||||
|
||||
virtual ID3D11DeviceContext* getContext() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
virtual ID3D11Buffer* getbtDX11Buffer() const
|
||||
{
|
||||
return m_vertexBuffer;
|
||||
}
|
||||
|
||||
virtual ID3D11UnorderedAccessView* getDX11UAV() const
|
||||
{
|
||||
return m_vertexBufferUAV;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_DX11_H
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
#define BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
|
||||
class btSoftBodyLinkData;
|
||||
class btSoftBodyLinkData::LinkDescription;
|
||||
|
||||
struct ID3D11Device;
|
||||
struct ID3D11DeviceContext;
|
||||
|
||||
class btSoftBodyVertexDataDX11 : public btSoftBodyVertexData
|
||||
{
|
||||
protected:
|
||||
bool m_onGPU;
|
||||
ID3D11Device *m_d3dDevice;
|
||||
ID3D11DeviceContext *m_d3dDeviceContext;
|
||||
|
||||
public:
|
||||
btDX11Buffer<int> m_dx11ClothIdentifier;
|
||||
btDX11Buffer<Vectormath::Aos::Point3> m_dx11VertexPosition;
|
||||
btDX11Buffer<Vectormath::Aos::Point3> m_dx11VertexPreviousPosition;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexVelocity;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexForceAccumulator;
|
||||
btDX11Buffer<Vectormath::Aos::Vector3> m_dx11VertexNormal;
|
||||
btDX11Buffer<float> m_dx11VertexInverseMass;
|
||||
btDX11Buffer<float> m_dx11VertexArea;
|
||||
btDX11Buffer<int> m_dx11VertexTriangleCount;
|
||||
|
||||
|
||||
//ID3D11Buffer* readBackBuffer;
|
||||
|
||||
public:
|
||||
btSoftBodyVertexDataDX11( ID3D11Device *d3dDevice, ID3D11DeviceContext *d3dDeviceContext );
|
||||
virtual ~btSoftBodyVertexDataDX11();
|
||||
|
||||
virtual bool onAccelerator();
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BHODY_SOLVER_VERTEX_DATA_DX11_H
|
||||
|
||||
|
|
@ -0,0 +1,481 @@
|
|||
/*
|
||||
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_DX11_SOLVER_H
|
||||
#define BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolverVertexBuffer_DX11.h"
|
||||
#include "btSoftBodySolverLinkData_DX11.h"
|
||||
#include "btSoftBodySolverVertexData_DX11.h"
|
||||
#include "btSoftBodySolverTriangleData_DX11.h"
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btDX11AcceleratedSoftBodyInterface
|
||||
{
|
||||
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 )
|
||||
{
|
||||
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:
|
||||
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
struct PrepareLinksCB
|
||||
{
|
||||
int numLinks;
|
||||
int padding0;
|
||||
int padding1;
|
||||
int padding2;
|
||||
};
|
||||
|
||||
struct SolvePositionsFromLinksKernelCB
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
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;
|
||||
};
|
||||
|
||||
struct VSolveLinksCB
|
||||
{
|
||||
int startLink;
|
||||
int numLinks;
|
||||
float kst;
|
||||
int padding;
|
||||
};
|
||||
|
||||
|
||||
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. */
|
||||
btSoftBodyLinkDataDX11 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< btDX11AcceleratedSoftBodyInterface * > 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;
|
||||
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 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;
|
||||
|
||||
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 );
|
||||
|
||||
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 );
|
||||
|
||||
btDX11AcceleratedSoftBodyInterface *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 );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
public:
|
||||
btDX11SoftBodySolver(ID3D11Device * dx11Device, ID3D11DeviceContext* dx11Context);
|
||||
|
||||
virtual ~btDX11SoftBodySolver();
|
||||
|
||||
|
||||
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 );
|
||||
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_ACCELERATED_SOFT_BODY_DX11_SOLVER_H
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,432 @@
|
|||
/*
|
||||
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 "vectormath/vmInclude.h"
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolverVertexBuffer_DX11.h"
|
||||
#include "btSoftBodySolverLinkData_DX11SIMDAware.h"
|
||||
#include "btSoftBodySolverVertexData_DX11.h"
|
||||
#include "btSoftBodySolverTriangleData_DX11.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
|
||||
class btDX11SIMDAwareSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
struct SolvePositionsFromLinksKernelCB
|
||||
{
|
||||
int startWave;
|
||||
int numWaves;
|
||||
float kst;
|
||||
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;
|
||||
|
||||
/** 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 );
|
||||
|
||||
// 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 );
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_DX11_SOLVER_SIMDAWARE_H
|
||||
|
||||
|
|
@ -0,0 +1,284 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="MinSizeRel|Win32">
|
||||
<Configuration>MinSizeRel</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="RelWithDebInfo|Win32">
|
||||
<Configuration>RelWithDebInfo</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGUID>{14266978-3E62-4DC3-AAEF-CB815EEB708D}</ProjectGUID>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<Platform>Win32</Platform>
|
||||
<ProjectName>BulletSoftBodySolvers_OpenCL_Mini</ProjectName>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'" Label="Configuration">
|
||||
<ConfigurationType>StaticLibrary</ConfigurationType>
|
||||
<UseOfMfc>false</UseOfMfc>
|
||||
<CharacterSet>MultiByte</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> </ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup>
|
||||
<_ProjectFileVersion>10.0.20506.1</_ProjectFileVersion>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\lib\Debug\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">BulletSoftBodySolvers_OpenCL_Mini.dir\Debug\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">BulletSoftBodySolvers_OpenCL_Mini</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">.lib</TargetExt>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\lib\Release\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">BulletSoftBodySolvers_OpenCL_Mini.dir\Release\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">BulletSoftBodySolvers_OpenCL_Mini</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">.lib</TargetExt>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\lib\MinSizeRel\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">BulletSoftBodySolvers_OpenCL_Mini.dir\MinSizeRel\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">BulletSoftBodySolvers_OpenCL_Mini</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">.lib</TargetExt>
|
||||
<OutDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\lib\RelWithDebInfo\</OutDir>
|
||||
<IntDir Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">BulletSoftBodySolvers_OpenCL_Mini.dir\RelWithDebInfo\</IntDir>
|
||||
<TargetName Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">BulletSoftBodySolvers_OpenCL_Mini</TargetName>
|
||||
<TargetExt Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">.lib</TargetExt>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions> /Zm1000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<BasicRuntimeChecks>EnableFastChecks</BasicRuntimeChecks>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>Disabled</InlineFunctionExpansion>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_DEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR="Debug";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>Debug</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/lib/Debug/BulletSoftBodySolvers_OpenCL_Mini.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_DEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR=\"Debug\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions> /Zm1000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>AnySuitable</InlineFunctionExpansion>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat></DebugInformationFormat>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR="Release";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>Release</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/lib/Release/BulletSoftBodySolvers_OpenCL_Mini.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR=\"Release\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions> /Zm1000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<Optimization>MinSpace</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat></DebugInformationFormat>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR="MinSizeRel";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>MinSizeRel</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/lib/MinSizeRel/BulletSoftBodySolvers_OpenCL_Mini.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR=\"MinSizeRel\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">
|
||||
<ClCompile>
|
||||
<AdditionalOptions> /Zm1000 %(AdditionalOptions)</AdditionalOptions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<CompileAs>CompileAsCpp</CompileAs>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<EnableEnhancedInstructionSet>StreamingSIMDExtensions</EnableEnhancedInstructionSet>
|
||||
<ExceptionHandling>Sync</ExceptionHandling>
|
||||
<FloatingPointModel>Fast</FloatingPointModel>
|
||||
<InlineFunctionExpansion>OnlyExplicitInline</InlineFunctionExpansion>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<RuntimeTypeInfo>true</RuntimeTypeInfo>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR="RelWithDebInfo";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AssemblerListingLocation>RelWithDebInfo</AssemblerListingLocation>
|
||||
<ObjectFileName>$(IntDir)</ObjectFileName>
|
||||
<ProgramDataBaseFileName>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/lib/RelWithDebInfo/BulletSoftBodySolvers_OpenCL_Mini.pdb</ProgramDataBaseFileName>
|
||||
</ClCompile>
|
||||
<ResourceCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;USE_GRAPHICAL_BENCHMARK;_IRR_STATIC_LIB_;_CRT_SECURE_NO_WARNINGS;_CRT_SECURE_NO_DEPRECATE;_SCL_SECURE_NO_WARNINGS;USE_MINICL;CMAKE_INTDIR=\"RelWithDebInfo\";%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ResourceCompile>
|
||||
<Midl>
|
||||
<AdditionalIncludeDirectories>C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/Glut;C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<OutputDirectory>$(IntDir)</OutputDirectory>
|
||||
<HeaderFileName>%(Filename).h</HeaderFileName>
|
||||
<TypeLibraryName>%(Filename).tlb</TypeLibraryName>
|
||||
<InterfaceIdentifierFileName>%(Filename)_i.c</InterfaceIdentifierFileName>
|
||||
<ProxyFileName>%(Filename)_p.c</ProxyFileName>
|
||||
</Midl>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="CMakeLists.txt">
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">Building Custom Rule C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">setlocal
|
||||
"C:\Program Files\CMake 2.8\bin\cmake.exe" "-HC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" "-BC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" --check-stamp-file "C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp"
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">Building Custom Rule C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">setlocal
|
||||
"C:\Program Files\CMake 2.8\bin\cmake.exe" "-HC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" "-BC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" --check-stamp-file "C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp"
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">Building Custom Rule C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">setlocal
|
||||
"C:\Program Files\CMake 2.8\bin\cmake.exe" "-HC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" "-BC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" --check-stamp-file "C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp"
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='MinSizeRel|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp</Outputs>
|
||||
<Message Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">Building Custom Rule C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt</Message>
|
||||
<Command Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">setlocal
|
||||
"C:\Program Files\CMake 2.8\bin\cmake.exe" "-HC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" "-BC:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77" --check-stamp-file "C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp"
|
||||
if %errorlevel% neq 0 goto :cmEnd
|
||||
:cmEnd
|
||||
endlocal & call :cmErrorLevel %errorlevel% & goto :cmDone
|
||||
:cmErrorLevel
|
||||
exit /b %1
|
||||
:cmDone
|
||||
if %errorlevel% neq 0 goto :VCEnd</Command>
|
||||
<AdditionalInputs Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeLists.txt;%(AdditionalInputs)</AdditionalInputs>
|
||||
<Outputs Condition="'$(Configuration)|$(Platform)'=='RelWithDebInfo|Win32'">C:\Documents and Settings\Robert MacGregor\Desktop\bullet-2.77\src\BulletMultiThreaded\GpuSoftBodySolvers\OpenCL\MiniCL\CMakeFiles\generate.stamp</Outputs>
|
||||
</CustomBuild>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\btSoftBodySolver_OpenCL.h" />
|
||||
<ClInclude Include="..\..\CPU\btSoftBodySolverData.h" />
|
||||
<ClInclude Include="..\btSoftBodySolverVertexData_OpenCL.h" />
|
||||
<ClInclude Include="..\btSoftBodySolverTriangleData_OpenCL.h" />
|
||||
<ClInclude Include="..\btSoftBodySolverLinkData_OpenCL.h" />
|
||||
<ClInclude Include="..\btSoftBodySolverBuffer_OpenCL.h" />
|
||||
<ClCompile Include="..\btSoftBodySolver_OpenCL.cpp" />
|
||||
<None Include="..\OpenCLC10\UpdateNormals.cl" />
|
||||
<None Include="..\OpenCLC10\Integrate.cl" />
|
||||
<None Include="..\OpenCLC10\UpdatePositions.cl" />
|
||||
<None Include="..\OpenCLC10\UpdateNodes.cl" />
|
||||
<None Include="..\OpenCLC10\SolvePositions.cl" />
|
||||
<None Include="..\OpenCLC10\UpdatePositionsFromVelocities.cl" />
|
||||
<None Include="..\OpenCLC10\ApplyForces.cl" />
|
||||
<None Include="..\OpenCLC10\PrepareLinks.cl" />
|
||||
<None Include="..\OpenCLC10\VSolveLinks.cl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/ZERO_CHECK.vcxproj">
|
||||
<Project>C0E57694-ABCD-4C08-B9A4-F249AD836120</Project>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\btSoftBodySolver_OpenCL.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\btSoftBodySolver_OpenCL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\..\CPU\btSoftBodySolverData.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\btSoftBodySolverVertexData_OpenCL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\btSoftBodySolverTriangleData_OpenCL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\btSoftBodySolverLinkData_OpenCL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\btSoftBodySolverBuffer_OpenCL.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<CustomBuild Include="CMakeLists.txt" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\OpenCLC10\UpdateNormals.cl" />
|
||||
<None Include="..\OpenCLC10\Integrate.cl" />
|
||||
<None Include="..\OpenCLC10\UpdatePositions.cl" />
|
||||
<None Include="..\OpenCLC10\UpdateNodes.cl" />
|
||||
<None Include="..\OpenCLC10\SolvePositions.cl" />
|
||||
<None Include="..\OpenCLC10\UpdatePositionsFromVelocities.cl" />
|
||||
<None Include="..\OpenCLC10\ApplyForces.cl" />
|
||||
<None Include="..\OpenCLC10\PrepareLinks.cl" />
|
||||
<None Include="..\OpenCLC10\VSolveLinks.cl" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{C487BFC5-6BC8-47B3-88D6-C5D9B883A3BD}</UniqueIdentifier>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{30F7A2E9-D73F-45A4-9CAC-B039D62294E1}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
</Project>
|
||||
|
|
@ -0,0 +1 @@
|
|||
# CMake generation timestamp file this directory.
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
# CMake generation dependency list for this directory.
|
||||
C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL/CMakeLists.txt
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
INCLUDE_DIRECTORIES(
|
||||
${BULLET_PHYSICS_SOURCE_DIR}/src
|
||||
)
|
||||
|
||||
ADD_DEFINITIONS(-DUSE_MINICL)
|
||||
|
||||
|
||||
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_SRCS
|
||||
../btSoftBodySolver_OpenCL.cpp
|
||||
)
|
||||
|
||||
SET(BulletSoftBodyOpenCLSolvers_HDRS
|
||||
../btSoftBodySolver_OpenCL.h
|
||||
../../CPU/btSoftBodySolverData.h
|
||||
../btSoftBodySolverVertexData_OpenCL.h
|
||||
../btSoftBodySolverTriangleData_OpenCL.h
|
||||
../btSoftBodySolverLinkData_OpenCL.h
|
||||
../btSoftBodySolverBuffer_OpenCL.h
|
||||
)
|
||||
|
||||
# OpenCL and HLSL Shaders.
|
||||
# Build rules generated to stringify these into headers
|
||||
# which are needed by some of the sources
|
||||
SET(BulletSoftBodyOpenCLSolvers_Shaders
|
||||
# OutputToVertexArray
|
||||
UpdateNormals
|
||||
Integrate
|
||||
UpdatePositions
|
||||
UpdateNodes
|
||||
SolvePositions
|
||||
UpdatePositionsFromVelocities
|
||||
ApplyForces
|
||||
PrepareLinks
|
||||
VSolveLinks
|
||||
)
|
||||
|
||||
foreach(f ${BulletSoftBodyOpenCLSolvers_Shaders})
|
||||
LIST(APPEND BulletSoftBodyOpenCLSolvers_OpenCLC "../OpenCLC10/${f}.cl")
|
||||
endforeach(f)
|
||||
|
||||
|
||||
|
||||
ADD_LIBRARY(BulletSoftBodySolvers_OpenCL_Mini
|
||||
${BulletSoftBodyOpenCLSolvers_SRCS}
|
||||
${BulletSoftBodyOpenCLSolvers_HDRS}
|
||||
${BulletSoftBodyOpenCLSolvers_OpenCLC}
|
||||
)
|
||||
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES VERSION ${BULLET_VERSION})
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES SOVERSION ${BULLET_VERSION})
|
||||
IF (BUILD_SHARED_LIBS)
|
||||
TARGET_LINK_LIBRARIES(BulletSoftBodySolvers_OpenCL_Mini MiniCL BulletMultiThreaded BulletSoftBody)
|
||||
ENDIF (BUILD_SHARED_LIBS)
|
||||
|
||||
|
||||
IF (INSTALL_LIBS)
|
||||
IF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
IF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini DESTINATION .)
|
||||
ELSE (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
INSTALL(TARGETS BulletSoftBodySolvers_OpenCL_Mini DESTINATION lib${LIB_SUFFIX})
|
||||
#headers are already installed by BulletMultiThreaded library
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (${CMAKE_MAJOR_VERSION}.${CMAKE_MINOR_VERSION} GREATER 2.5)
|
||||
|
||||
IF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES FRAMEWORK true)
|
||||
SET_TARGET_PROPERTIES(BulletSoftBodySolvers_OpenCL_Mini PROPERTIES PUBLIC_HEADER "${BulletSoftBodyOpenCLSolvers_HDRS}")
|
||||
ENDIF (APPLE AND BUILD_SHARED_LIBS AND FRAMEWORK)
|
||||
ENDIF (NOT INTERNAL_CREATE_DISTRIBUTABLE_MSVC_PROJECTFILES)
|
||||
ENDIF (INSTALL_LIBS)
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include <MiniCL/cl_MiniCL_Defs.h>
|
||||
|
||||
#define MSTRINGIFY(A) A
|
||||
#include "../OpenCLC10/ApplyForces.cl"
|
||||
#include "../OpenCLC10/Integrate.cl"
|
||||
#include "../OpenCLC10/PrepareLinks.cl"
|
||||
#include "../OpenCLC10/SolvePositions.cl"
|
||||
#include "../OpenCLC10/UpdateNodes.cl"
|
||||
#include "../OpenCLC10/UpdateNormals.cl"
|
||||
#include "../OpenCLC10/UpdatePositions.cl"
|
||||
#include "../OpenCLC10/UpdatePositionsFromVelocities.cl"
|
||||
//#include "../OpenCLC10/VSolveLinks.cl"
|
||||
|
||||
MINICL_REGISTER(PrepareLinksKernel)
|
||||
MINICL_REGISTER(UpdatePositionsFromVelocitiesKernel)
|
||||
MINICL_REGISTER(SolvePositionsFromLinksKernel)
|
||||
MINICL_REGISTER(updateVelocitiesFromPositionsWithVelocitiesKernel)
|
||||
MINICL_REGISTER(updateVelocitiesFromPositionsWithoutVelocitiesKernel)
|
||||
MINICL_REGISTER(IntegrateKernel)
|
||||
MINICL_REGISTER(ApplyForcesKernel)
|
||||
MINICL_REGISTER(ResetNormalsAndAreasKernel)
|
||||
MINICL_REGISTER(NormalizeNormalsAndAreasKernel)
|
||||
MINICL_REGISTER(UpdateSoftBodiesKernel)
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,29 @@
|
|||
# Install script for directory: C:/Documents and Settings/Robert MacGregor/Desktop/bullet-2.77/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/MiniCL
|
||||
|
||||
# Set the install prefix
|
||||
IF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
SET(CMAKE_INSTALL_PREFIX "C:/Program Files/BULLET_PHYSICS")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_PREFIX)
|
||||
STRING(REGEX REPLACE "/$" "" CMAKE_INSTALL_PREFIX "${CMAKE_INSTALL_PREFIX}")
|
||||
|
||||
# Set the install configuration name.
|
||||
IF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
IF(BUILD_TYPE)
|
||||
STRING(REGEX REPLACE "^[^A-Za-z0-9_]+" ""
|
||||
CMAKE_INSTALL_CONFIG_NAME "${BUILD_TYPE}")
|
||||
ELSE(BUILD_TYPE)
|
||||
SET(CMAKE_INSTALL_CONFIG_NAME "Release")
|
||||
ENDIF(BUILD_TYPE)
|
||||
MESSAGE(STATUS "Install configuration: \"${CMAKE_INSTALL_CONFIG_NAME}\"")
|
||||
ENDIF(NOT DEFINED CMAKE_INSTALL_CONFIG_NAME)
|
||||
|
||||
# Set the component getting installed.
|
||||
IF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
IF(COMPONENT)
|
||||
MESSAGE(STATUS "Install component: \"${COMPONENT}\"")
|
||||
SET(CMAKE_INSTALL_COMPONENT "${COMPONENT}")
|
||||
ELSE(COMPONENT)
|
||||
SET(CMAKE_INSTALL_COMPONENT)
|
||||
ENDIF(COMPONENT)
|
||||
ENDIF(NOT CMAKE_INSTALL_COMPONENT)
|
||||
|
||||
|
|
@ -0,0 +1,194 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
|
||||
// OpenCL support
|
||||
|
||||
#ifdef USE_MINICL
|
||||
#include "MiniCL/cl.h"
|
||||
#else //USE_MINICL
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/OpenCL.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#endif //__APPLE__
|
||||
#endif//USE_MINICL
|
||||
|
||||
#ifndef SAFE_RELEASE
|
||||
#define SAFE_RELEASE(p) { if(p) { (p)->Release(); (p)=NULL; } }
|
||||
#endif
|
||||
|
||||
template <typename ElementType> class btOpenCLBuffer
|
||||
{
|
||||
public:
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_clContext;
|
||||
cl_mem m_buffer;
|
||||
|
||||
|
||||
|
||||
btAlignedObjectArray< ElementType > * m_CPUBuffer;
|
||||
|
||||
int m_gpuSize;
|
||||
bool m_onGPU;
|
||||
bool m_readOnlyOnGPU;
|
||||
bool m_allocated;
|
||||
|
||||
|
||||
bool createBuffer( cl_mem* preexistingBuffer = 0)
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
|
||||
if( preexistingBuffer )
|
||||
{
|
||||
m_buffer = *preexistingBuffer;
|
||||
}
|
||||
else {
|
||||
|
||||
cl_mem_flags flags= m_readOnlyOnGPU ? CL_MEM_READ_ONLY : CL_MEM_READ_WRITE;
|
||||
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
m_buffer = clCreateBuffer(m_clContext, flags, size, 0, &err);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "Buffer::Buffer(m_buffer)");
|
||||
}
|
||||
}
|
||||
|
||||
m_gpuSize = m_CPUBuffer->size();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public:
|
||||
btOpenCLBuffer( cl_command_queue commandQue,cl_context ctx, btAlignedObjectArray< ElementType >* CPUBuffer, bool readOnly)
|
||||
:m_cqCommandQue(commandQue),
|
||||
m_clContext(ctx),
|
||||
m_CPUBuffer(CPUBuffer),
|
||||
m_gpuSize(0),
|
||||
m_onGPU(false),
|
||||
m_readOnlyOnGPU(readOnly),
|
||||
m_allocated(false)
|
||||
{
|
||||
}
|
||||
|
||||
~btOpenCLBuffer()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool moveToGPU()
|
||||
{
|
||||
|
||||
|
||||
cl_int err;
|
||||
|
||||
if( (m_CPUBuffer->size() != m_gpuSize) )
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
|
||||
if( !m_onGPU && m_CPUBuffer->size() > 0 )
|
||||
{
|
||||
if (!m_allocated || (m_CPUBuffer->size() != m_gpuSize)) {
|
||||
if (!createBuffer()) {
|
||||
return false;
|
||||
}
|
||||
m_allocated = true;
|
||||
}
|
||||
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
err = clEnqueueWriteBuffer(m_cqCommandQue,m_buffer,
|
||||
CL_FALSE,
|
||||
0,
|
||||
size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueWriteBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = true;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
}
|
||||
|
||||
bool moveFromGPU()
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
err = clEnqueueReadBuffer(m_cqCommandQue,
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,
|
||||
size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)" );
|
||||
}
|
||||
|
||||
m_onGPU = false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool copyFromGPU()
|
||||
{
|
||||
|
||||
cl_int err;
|
||||
size_t size = m_CPUBuffer->size() * sizeof(ElementType);
|
||||
|
||||
if (m_CPUBuffer->size() > 0) {
|
||||
if (m_onGPU && !m_readOnlyOnGPU) {
|
||||
err = clEnqueueReadBuffer(m_cqCommandQue,
|
||||
m_buffer,
|
||||
CL_TRUE,
|
||||
0,size,
|
||||
&((*m_CPUBuffer)[0]),0,0,0);
|
||||
|
||||
if( err != CL_SUCCESS )
|
||||
{
|
||||
btAssert( "CommandQueue::enqueueReadBuffer(m_buffer)");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
virtual void changedOnCPU()
|
||||
{
|
||||
m_onGPU = false;
|
||||
}
|
||||
}; // class btOpenCLBuffer
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_BUFFER_OPENCL_H
|
||||
|
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyLinkDataOpenCL : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
|
||||
|
||||
btOpenCLBuffer<LinkNodePair> m_clLinks;
|
||||
btOpenCLBuffer<float> m_clLinkStrength;
|
||||
btOpenCLBuffer<float> m_clLinksMassLSC;
|
||||
btOpenCLBuffer<float> m_clLinksRestLengthSquared;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clLinksCLength;
|
||||
btOpenCLBuffer<float> m_clLinksLengthRatio;
|
||||
btOpenCLBuffer<float> m_clLinksRestLength;
|
||||
btOpenCLBuffer<float> m_clLinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_batchStartLengths;
|
||||
|
||||
btSoftBodyLinkDataOpenCL(cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyLinkDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt(
|
||||
const LinkDescription &link,
|
||||
int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_H
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/Shared/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
|
||||
|
||||
class btSoftBodyLinkDataOpenCLSIMDAware : public btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
|
||||
const int m_wavefrontSize;
|
||||
const int m_linksPerWorkItem;
|
||||
const int m_maxLinksPerWavefront;
|
||||
int m_maxBatchesWithinWave;
|
||||
int m_maxVerticesWithinWave;
|
||||
int m_numWavefronts;
|
||||
|
||||
int m_maxVertex;
|
||||
|
||||
struct NumBatchesVerticesPair
|
||||
{
|
||||
int numBatches;
|
||||
int numVertices;
|
||||
};
|
||||
|
||||
btAlignedObjectArray<int> m_linksPerWavefront;
|
||||
btAlignedObjectArray<NumBatchesVerticesPair> m_numBatchesAndVerticesWithinWaves;
|
||||
btOpenCLBuffer< NumBatchesVerticesPair > m_clNumBatchesAndVerticesWithinWaves;
|
||||
|
||||
// All arrays here will contain batches of m_maxLinksPerWavefront links
|
||||
// ordered by wavefront.
|
||||
// with either global vertex pairs or local vertex pairs
|
||||
btAlignedObjectArray< int > m_wavefrontVerticesGlobalAddresses; // List of global vertices per wavefront
|
||||
btOpenCLBuffer<int> m_clWavefrontVerticesGlobalAddresses;
|
||||
btAlignedObjectArray< LinkNodePair > m_linkVerticesLocalAddresses; // Vertex pair for the link
|
||||
btOpenCLBuffer<LinkNodePair> m_clLinkVerticesLocalAddresses;
|
||||
btOpenCLBuffer<float> m_clLinkStrength;
|
||||
btOpenCLBuffer<float> m_clLinksMassLSC;
|
||||
btOpenCLBuffer<float> m_clLinksRestLengthSquared;
|
||||
btOpenCLBuffer<float> m_clLinksRestLength;
|
||||
btOpenCLBuffer<float> m_clLinksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
struct BatchPair
|
||||
{
|
||||
int start;
|
||||
int length;
|
||||
|
||||
BatchPair() :
|
||||
start(0),
|
||||
length(0)
|
||||
{
|
||||
}
|
||||
|
||||
BatchPair( int s, int l ) :
|
||||
start( s ),
|
||||
length( l )
|
||||
{
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_linkAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
btAlignedObjectArray< BatchPair > m_wavefrontBatchStartLengths;
|
||||
|
||||
btSoftBodyLinkDataOpenCLSIMDAware(cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyLinkDataOpenCLSIMDAware();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt(
|
||||
const LinkDescription &link,
|
||||
int linkIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire link set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
|
||||
int getMaxVerticesPerWavefront()
|
||||
{
|
||||
return m_maxVerticesWithinWave;
|
||||
}
|
||||
|
||||
int getWavefrontSize()
|
||||
{
|
||||
return m_wavefrontSize;
|
||||
}
|
||||
|
||||
int getLinksPerWorkItem()
|
||||
{
|
||||
return m_linksPerWorkItem;
|
||||
}
|
||||
|
||||
int getMaxLinksPerWavefront()
|
||||
{
|
||||
return m_maxLinksPerWavefront;
|
||||
}
|
||||
|
||||
int getMaxBatchesPerWavefront()
|
||||
{
|
||||
return m_maxBatchesWithinWave;
|
||||
}
|
||||
|
||||
int getNumWavefronts()
|
||||
{
|
||||
return m_numWavefronts;
|
||||
}
|
||||
|
||||
NumBatchesVerticesPair getNumBatchesAndVerticesWithinWavefront( int wavefront )
|
||||
{
|
||||
return m_numBatchesAndVerticesWithinWaves[wavefront];
|
||||
}
|
||||
|
||||
int getVertexGlobalAddresses( int vertexIndex )
|
||||
{
|
||||
return m_wavefrontVerticesGlobalAddresses[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get post-batching local addresses of the vertex pair for a link assuming all vertices used by a wavefront are loaded locally.
|
||||
*/
|
||||
LinkNodePair getVertexPairLocalAddresses( int linkIndex )
|
||||
{
|
||||
return m_linkVerticesLocalAddresses[linkIndex];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_LINK_DATA_OPENCL_SIMDAWARE_H
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
#define BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
|
||||
#include "btSoftBodySolver_OpenCL.h"
|
||||
|
||||
/**
|
||||
* Class to manage movement of data from a solver to a given target.
|
||||
* This version is the CL to GL interop version.
|
||||
*/
|
||||
class btSoftBodySolverOutputCLtoGL : public btSoftBodySolverOutput
|
||||
{
|
||||
protected:
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_cxMainContext;
|
||||
CLFunctions clFunctions;
|
||||
|
||||
cl_kernel outputToVertexArrayWithNormalsKernel;
|
||||
cl_kernel outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
bool m_shadersInitialized;
|
||||
|
||||
virtual bool checkInitialized();
|
||||
virtual bool buildShaders();
|
||||
void releaseKernels();
|
||||
public:
|
||||
btSoftBodySolverOutputCLtoGL(cl_command_queue cqCommandQue, cl_context cxMainContext) :
|
||||
m_cqCommandQue( cqCommandQue ),
|
||||
m_cxMainContext( cxMainContext ),
|
||||
clFunctions(cqCommandQue, cxMainContext),
|
||||
outputToVertexArrayWithNormalsKernel( 0 ),
|
||||
outputToVertexArrayWithoutNormalsKernel( 0 ),
|
||||
m_shadersInitialized( false )
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodySolverOutputCLtoGL()
|
||||
{
|
||||
releaseKernels();
|
||||
}
|
||||
|
||||
/** Output current computed vertex data to the vertex buffers for all cloths in the solver. */
|
||||
virtual void copySoftBodyToVertexBuffer( const btSoftBody * const softBody, btVertexBufferDescriptor *vertexBuffer );
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OUTPUT_CL_TO_GL_H
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyTriangleDataOpenCL : public btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
bool m_onGPU;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
btOpenCLBuffer<btSoftBodyTriangleData::TriangleNodeSet> m_clVertexIndices;
|
||||
btOpenCLBuffer<float> m_clArea;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clNormal;
|
||||
|
||||
/**
|
||||
* Link addressing information for each cloth.
|
||||
* Allows link locations to be computed independently of data batching.
|
||||
*/
|
||||
btAlignedObjectArray< int > m_triangleAddresses;
|
||||
|
||||
/**
|
||||
* Start and length values for computation batches over link data.
|
||||
*/
|
||||
struct btSomePair
|
||||
{
|
||||
btSomePair() {}
|
||||
btSomePair(int f,int s)
|
||||
:first(f),second(s)
|
||||
{
|
||||
}
|
||||
int first;
|
||||
int second;
|
||||
};
|
||||
btAlignedObjectArray< btSomePair > m_batchStartLengths;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleDataOpenCL( cl_command_queue queue, cl_context ctx );
|
||||
|
||||
virtual ~btSoftBodyTriangleDataOpenCL();
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createTriangles( int numTriangles );
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setTriangleAt( const btSoftBodyTriangleData::TriangleDescription &triangle, int triangleIndex );
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
|
||||
/**
|
||||
* Generate (and later update) the batching for the entire triangle set.
|
||||
* This redoes a lot of work because it batches the entire set when each cloth is inserted.
|
||||
* In theory we could delay it until just before we need the cloth.
|
||||
* It's a one-off overhead, though, so that is a later optimisation.
|
||||
*/
|
||||
void generateBatches();
|
||||
}; // class btSoftBodyTriangleDataOpenCL
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_TRIANGLE_DATA_OPENCL_H
|
||||
|
||||
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolverVertexBuffer.h"
|
||||
#ifdef USE_MINICL
|
||||
#include "MiniCL/cl.h"
|
||||
#else //USE_MINICL
|
||||
#ifdef __APPLE__
|
||||
#include <OpenCL/OpenCL.h>
|
||||
#else
|
||||
#include <CL/cl.h>
|
||||
#include <CL/cl_gl.h>
|
||||
#endif //__APPLE__
|
||||
#endif//USE_MINICL
|
||||
|
||||
|
||||
#ifdef _WIN32//for glut.h
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
//think different
|
||||
#if defined(__APPLE__) && !defined (VMDMESA)
|
||||
#include <OpenGL/OpenGL.h>
|
||||
#include <OpenGL/gl.h>
|
||||
#include <OpenGL/glu.h>
|
||||
#include <GLUT/glut.h>
|
||||
#else
|
||||
|
||||
|
||||
#ifdef _WINDOWS
|
||||
#include <windows.h>
|
||||
#include <GL/gl.h>
|
||||
#include <GL/glu.h>
|
||||
#else
|
||||
#include <GL/glut.h>
|
||||
#endif //_WINDOWS
|
||||
#endif //APPLE
|
||||
|
||||
|
||||
|
||||
class btOpenGLInteropVertexBufferDescriptor : public btVertexBufferDescriptor
|
||||
{
|
||||
protected:
|
||||
/** OpenCL context */
|
||||
cl_context m_context;
|
||||
|
||||
/** OpenCL command queue */
|
||||
cl_command_queue m_commandQueue;
|
||||
|
||||
/** OpenCL interop buffer */
|
||||
cl_mem m_buffer;
|
||||
|
||||
/** VBO in GL that is the basis of the interop buffer */
|
||||
GLuint m_openGLVBO;
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* context is the OpenCL context this interop buffer will work in.
|
||||
* queue is the command queue that kernels and data movement will be enqueued into.
|
||||
* openGLVBO is the OpenGL vertex buffer data will be copied into.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
*/
|
||||
btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride )
|
||||
{
|
||||
#ifndef USE_MINICL
|
||||
cl_int ciErrNum = CL_SUCCESS;
|
||||
m_context = context;
|
||||
m_commandQueue = cqCommandQue;
|
||||
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
|
||||
m_openGLVBO = openGLVBO;
|
||||
|
||||
m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
m_hasVertexPositions = true;
|
||||
#else
|
||||
btAssert(0);//MiniCL shouldn't get here
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* context is the OpenCL context this interop buffer will work in.
|
||||
* queue is the command queue that kernels and data movement will be enqueued into.
|
||||
* openGLVBO is the OpenGL vertex buffer data will be copied into.
|
||||
* vertexOffset is the offset in floats to the first vertex.
|
||||
* vertexStride is the stride in floats between vertices.
|
||||
* normalOffset is the offset in floats to the first normal.
|
||||
* normalStride is the stride in floats between normals.
|
||||
*/
|
||||
btOpenGLInteropVertexBufferDescriptor( cl_command_queue cqCommandQue, cl_context context, GLuint openGLVBO, int vertexOffset, int vertexStride, int normalOffset, int normalStride )
|
||||
{
|
||||
#ifndef USE_MINICL
|
||||
cl_int ciErrNum = CL_SUCCESS;
|
||||
m_context = context;
|
||||
m_commandQueue = cqCommandQue;
|
||||
|
||||
m_openGLVBO = openGLVBO;
|
||||
|
||||
m_buffer = clCreateFromGLBuffer(m_context, CL_MEM_WRITE_ONLY, openGLVBO, &ciErrNum);
|
||||
if( ciErrNum != CL_SUCCESS )
|
||||
{
|
||||
btAssert( 0 && "clEnqueueAcquireGLObjects(copySoftBodyToVertexBuffer)");
|
||||
}
|
||||
|
||||
m_vertexOffset = vertexOffset;
|
||||
m_vertexStride = vertexStride;
|
||||
m_hasVertexPositions = true;
|
||||
|
||||
m_normalOffset = normalOffset;
|
||||
m_normalStride = normalStride;
|
||||
m_hasNormals = true;
|
||||
#else
|
||||
btAssert(0);
|
||||
#endif //USE_MINICL
|
||||
|
||||
}
|
||||
|
||||
virtual ~btOpenGLInteropVertexBufferDescriptor()
|
||||
{
|
||||
clReleaseMemObject( m_buffer );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the type of the vertex buffer descriptor.
|
||||
*/
|
||||
virtual BufferTypes getBufferType() const
|
||||
{
|
||||
return OPENGL_BUFFER;
|
||||
}
|
||||
|
||||
virtual cl_context getContext() const
|
||||
{
|
||||
return m_context;
|
||||
}
|
||||
|
||||
virtual cl_mem getBuffer() const
|
||||
{
|
||||
return m_buffer;
|
||||
}
|
||||
};
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_BUFFER_OPENGL_H
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "BulletMultiThreaded/GpuSoftBodySolvers/CPU/btSoftBodySolverData.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
|
||||
|
||||
class btSoftBodyVertexDataOpenCL : public btSoftBodyVertexData
|
||||
{
|
||||
protected:
|
||||
bool m_onGPU;
|
||||
cl_command_queue m_queue;
|
||||
|
||||
public:
|
||||
btOpenCLBuffer<int> m_clClothIdentifier;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Point3> m_clVertexPreviousPosition;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexForceAccumulator;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clVertexNormal;
|
||||
btOpenCLBuffer<float> m_clVertexInverseMass;
|
||||
btOpenCLBuffer<float> m_clVertexArea;
|
||||
btOpenCLBuffer<int> m_clVertexTriangleCount;
|
||||
public:
|
||||
btSoftBodyVertexDataOpenCL( cl_command_queue queue, cl_context ctx);
|
||||
|
||||
virtual ~btSoftBodyVertexDataOpenCL();
|
||||
|
||||
virtual bool onAccelerator();
|
||||
|
||||
virtual bool moveToAccelerator();
|
||||
|
||||
virtual bool moveFromAccelerator();
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_VERTEX_DATA_OPENCL_H
|
||||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,344 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
#define BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
|
||||
#include "stddef.h" //for size_t
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
#include "BulletSoftBody/btSoftBodySolvers.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
#include "btSoftBodySolverLinkData_OpenCL.h"
|
||||
#include "btSoftBodySolverVertexData_OpenCL.h"
|
||||
#include "btSoftBodySolverTriangleData_OpenCL.h"
|
||||
|
||||
|
||||
/**
|
||||
* SoftBody class to maintain information about a soft body instance
|
||||
* within a solver.
|
||||
* This data addresses the main solver arrays.
|
||||
*/
|
||||
class btOpenCLAcceleratedSoftBodyInterface
|
||||
{
|
||||
protected:
|
||||
/** Current number of vertices that are part of this cloth */
|
||||
int m_numVertices;
|
||||
/** Maximum number of vertices allocated to be part of this cloth */
|
||||
int m_maxVertices;
|
||||
/** Current number of triangles that are part of this cloth */
|
||||
int m_numTriangles;
|
||||
/** Maximum number of triangles allocated to be part of this cloth */
|
||||
int m_maxTriangles;
|
||||
/** Index of first vertex in the world allocated to this cloth */
|
||||
int m_firstVertex;
|
||||
/** Index of first triangle in the world allocated to this cloth */
|
||||
int m_firstTriangle;
|
||||
/** Index of first link in the world allocated to this cloth */
|
||||
int m_firstLink;
|
||||
/** Maximum number of links allocated to this cloth */
|
||||
int m_maxLinks;
|
||||
/** Current number of links allocated to this cloth */
|
||||
int m_numLinks;
|
||||
|
||||
/** The actual soft body this data represents */
|
||||
btSoftBody *m_softBody;
|
||||
|
||||
|
||||
public:
|
||||
btOpenCLAcceleratedSoftBodyInterface( btSoftBody *softBody ) :
|
||||
m_softBody( softBody )
|
||||
{
|
||||
m_numVertices = 0;
|
||||
m_maxVertices = 0;
|
||||
m_numTriangles = 0;
|
||||
m_maxTriangles = 0;
|
||||
m_firstVertex = 0;
|
||||
m_firstTriangle = 0;
|
||||
m_firstLink = 0;
|
||||
m_maxLinks = 0;
|
||||
m_numLinks = 0;
|
||||
}
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_numVertices;
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_numTriangles;
|
||||
}
|
||||
|
||||
int getMaxVertices()
|
||||
{
|
||||
return m_maxVertices;
|
||||
}
|
||||
|
||||
int getMaxTriangles()
|
||||
{
|
||||
return m_maxTriangles;
|
||||
}
|
||||
|
||||
int getFirstVertex()
|
||||
{
|
||||
return m_firstVertex;
|
||||
}
|
||||
|
||||
int getFirstTriangle()
|
||||
{
|
||||
return m_firstTriangle;
|
||||
}
|
||||
|
||||
// TODO: All of these set functions will have to do checks and
|
||||
// update the world because restructuring of the arrays will be necessary
|
||||
// Reasonable use of "friend"?
|
||||
void setNumVertices( int numVertices )
|
||||
{
|
||||
m_numVertices = numVertices;
|
||||
}
|
||||
|
||||
void setNumTriangles( int numTriangles )
|
||||
{
|
||||
m_numTriangles = numTriangles;
|
||||
}
|
||||
|
||||
void setMaxVertices( int maxVertices )
|
||||
{
|
||||
m_maxVertices = maxVertices;
|
||||
}
|
||||
|
||||
void setMaxTriangles( int maxTriangles )
|
||||
{
|
||||
m_maxTriangles = maxTriangles;
|
||||
}
|
||||
|
||||
void setFirstVertex( int firstVertex )
|
||||
{
|
||||
m_firstVertex = firstVertex;
|
||||
}
|
||||
|
||||
void setFirstTriangle( int firstTriangle )
|
||||
{
|
||||
m_firstTriangle = firstTriangle;
|
||||
}
|
||||
|
||||
void setMaxLinks( int maxLinks )
|
||||
{
|
||||
m_maxLinks = maxLinks;
|
||||
}
|
||||
|
||||
void setNumLinks( int numLinks )
|
||||
{
|
||||
m_numLinks = numLinks;
|
||||
}
|
||||
|
||||
void setFirstLink( int firstLink )
|
||||
{
|
||||
m_firstLink = firstLink;
|
||||
}
|
||||
|
||||
int getMaxLinks()
|
||||
{
|
||||
return m_maxLinks;
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_numLinks;
|
||||
}
|
||||
|
||||
int getFirstLink()
|
||||
{
|
||||
return m_firstLink;
|
||||
}
|
||||
|
||||
btSoftBody* getSoftBody()
|
||||
{
|
||||
return m_softBody;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
class btOpenCLSoftBodySolver : public btSoftBodySolver
|
||||
{
|
||||
private:
|
||||
|
||||
btSoftBodyLinkDataOpenCL m_linkData;
|
||||
btSoftBodyVertexDataOpenCL m_vertexData;
|
||||
btSoftBodyTriangleDataOpenCL 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< btOpenCLAcceleratedSoftBodyInterface * > m_softBodySet;
|
||||
|
||||
/** Acceleration value to be applied to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothAcceleration;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothAcceleration;
|
||||
|
||||
/** Wind velocity to be applied normal to all non-static vertices in the solver.
|
||||
* Index n is cloth n, array sized by number of cloths in the world not the solver.
|
||||
*/
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_perClothWindVelocity;
|
||||
btOpenCLBuffer<Vectormath::Aos::Vector3> m_clPerClothWindVelocity;
|
||||
|
||||
/** Velocity damping factor */
|
||||
btAlignedObjectArray< float > m_perClothDampingFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDampingFactor;
|
||||
|
||||
/** Velocity correction coefficient */
|
||||
btAlignedObjectArray< float > m_perClothVelocityCorrectionCoefficient;
|
||||
btOpenCLBuffer<float> m_clPerClothVelocityCorrectionCoefficient;
|
||||
|
||||
/** Lift parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothLiftFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothLiftFactor;
|
||||
|
||||
/** Drag parameter for wind effect on cloth. */
|
||||
btAlignedObjectArray< float > m_perClothDragFactor;
|
||||
btOpenCLBuffer<float> m_clPerClothDragFactor;
|
||||
|
||||
/** Density of the medium in which each cloth sits */
|
||||
btAlignedObjectArray< float > m_perClothMediumDensity;
|
||||
btOpenCLBuffer<float> m_clPerClothMediumDensity;
|
||||
|
||||
cl_kernel prepareLinksKernel;
|
||||
cl_kernel solvePositionsFromLinksKernel;
|
||||
cl_kernel updateConstantsKernel;
|
||||
cl_kernel integrateKernel;
|
||||
cl_kernel addVelocityKernel;
|
||||
cl_kernel updatePositionsFromVelocitiesKernel;
|
||||
cl_kernel updateVelocitiesFromPositionsWithoutVelocitiesKernel;
|
||||
cl_kernel updateVelocitiesFromPositionsWithVelocitiesKernel;
|
||||
cl_kernel vSolveLinksKernel;
|
||||
cl_kernel resetNormalsAndAreasKernel;
|
||||
cl_kernel normalizeNormalsAndAreasKernel;
|
||||
cl_kernel updateSoftBodiesKernel;
|
||||
cl_kernel outputToVertexArrayWithNormalsKernel;
|
||||
cl_kernel outputToVertexArrayWithoutNormalsKernel;
|
||||
|
||||
cl_kernel outputToVertexArrayKernel;
|
||||
cl_kernel applyForcesKernel;
|
||||
cl_kernel collideSphereKernel;
|
||||
cl_kernel collideCylinderKernel;
|
||||
|
||||
cl_command_queue m_cqCommandQue;
|
||||
cl_context m_cxMainContext;
|
||||
|
||||
size_t m_defaultWorkGroupSize;
|
||||
|
||||
|
||||
/**
|
||||
* Compile a compute shader kernel from a string and return the appropriate cl_kernel object.
|
||||
*/
|
||||
cl_kernel compileCLKernelFromString( const char *shaderString, const char *shaderName );
|
||||
|
||||
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 );
|
||||
|
||||
btOpenCLAcceleratedSoftBodyInterface *findSoftBodyInterface( const btSoftBody* const softBody );
|
||||
|
||||
virtual void applyForces( float solverdt );
|
||||
|
||||
/**
|
||||
* Integrate motion on the solver.
|
||||
*/
|
||||
virtual void integrate( float solverdt );
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void prepareLinks();
|
||||
|
||||
void solveLinksForVelocity( int startLink, int numLinks, float kst );
|
||||
|
||||
void updatePositionsFromVelocities( float solverdt );
|
||||
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
void updateVelocitiesFromPositionsWithVelocities( float isolverdt );
|
||||
|
||||
void updateVelocitiesFromPositionsWithoutVelocities( float isolverdt );
|
||||
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
|
||||
public:
|
||||
btOpenCLSoftBodySolver(cl_command_queue queue,cl_context ctx);
|
||||
|
||||
virtual ~btOpenCLSoftBodySolver();
|
||||
|
||||
|
||||
|
||||
|
||||
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 void setDefaultWorkgroupSize(size_t workGroupSize)
|
||||
{
|
||||
m_defaultWorkGroupSize = workGroupSize;
|
||||
}
|
||||
virtual size_t getDefaultWorkGroupSize() const
|
||||
{
|
||||
return m_defaultWorkGroupSize;
|
||||
}
|
||||
}; // btOpenCLSoftBodySolver
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_H
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
#define BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
|
||||
#include "stddef.h" //for size_t
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
#include "btSoftBodySolver_OpenCL.h"
|
||||
#include "btSoftBodySolverBuffer_OpenCL.h"
|
||||
#include "btSoftBodySolverLinkData_OpenCLSIMDAware.h"
|
||||
#include "btSoftBodySolverVertexData_OpenCL.h"
|
||||
#include "btSoftBodySolverTriangleData_OpenCL.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class btOpenCLSoftBodySolverSIMDAware : public btOpenCLSoftBodySolver
|
||||
{
|
||||
protected:
|
||||
|
||||
|
||||
btSoftBodyLinkDataOpenCLSIMDAware m_linkData;
|
||||
|
||||
|
||||
|
||||
|
||||
virtual bool buildShaders();
|
||||
|
||||
|
||||
void updateConstants( float timeStep );
|
||||
|
||||
float computeTriangleArea(
|
||||
const Vectormath::Aos::Point3 &vertex0,
|
||||
const Vectormath::Aos::Point3 &vertex1,
|
||||
const Vectormath::Aos::Point3 &vertex2 );
|
||||
|
||||
|
||||
//////////////////////////////////////
|
||||
// Kernel dispatches
|
||||
void solveLinksForPosition( int startLink, int numLinks, float kst, float ti );
|
||||
|
||||
void solveCollisionsAndUpdateVelocities( float isolverdt );
|
||||
// End kernel dispatches
|
||||
/////////////////////////////////////
|
||||
|
||||
public:
|
||||
btOpenCLSoftBodySolverSIMDAware(cl_command_queue queue,cl_context ctx, bool bUpdateAchchoredNodePos = false);
|
||||
|
||||
virtual ~btOpenCLSoftBodySolverSIMDAware();
|
||||
|
||||
virtual SolverTypes getSolverType() const
|
||||
{
|
||||
return CL_SIMD_SOLVER;
|
||||
}
|
||||
|
||||
|
||||
virtual btSoftBodyLinkData &getLinkData();
|
||||
|
||||
|
||||
virtual void optimize( btAlignedObjectArray< btSoftBody * > &softBodies , bool forceUpdate=false);
|
||||
|
||||
virtual void solveConstraints( float solverdt );
|
||||
|
||||
}; // btOpenCLSoftBodySolverSIMDAware
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_OPENCL_SIMDAWARE_H
|
||||
|
|
@ -0,0 +1,748 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
#define BT_SOFT_BODY_SOLVER_DATA_H
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
|
||||
class btSoftBodyLinkData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a link as a set of three indices into the vertex array.
|
||||
*/
|
||||
class LinkNodePair
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
|
||||
LinkNodePair()
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
}
|
||||
|
||||
LinkNodePair( int v0, int v1 )
|
||||
{
|
||||
vertex0 = v0;
|
||||
vertex1 = v1;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Class describing a link for input into the system.
|
||||
*/
|
||||
class LinkDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
float m_linkLinearStiffness;
|
||||
float m_linkStrength;
|
||||
|
||||
public:
|
||||
|
||||
LinkDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_linkLinearStiffness = 1.0;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkDescription( int newVertex0, int newVertex1, float linkLinearStiffness )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_linkLinearStiffness = linkLinearStiffness;
|
||||
m_linkStrength = 1.0;
|
||||
}
|
||||
|
||||
LinkNodePair getVertexPair() const
|
||||
{
|
||||
LinkNodePair nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
return nodes;
|
||||
}
|
||||
|
||||
void setVertex0( int vertex )
|
||||
{
|
||||
m_vertex0 = vertex;
|
||||
}
|
||||
|
||||
void setVertex1( int vertex )
|
||||
{
|
||||
m_vertex1 = vertex;
|
||||
}
|
||||
|
||||
void setLinkLinearStiffness( float linearStiffness )
|
||||
{
|
||||
m_linkLinearStiffness = linearStiffness;
|
||||
}
|
||||
|
||||
void setLinkStrength( float strength )
|
||||
{
|
||||
m_linkStrength = strength;
|
||||
}
|
||||
|
||||
int getVertex0() const
|
||||
{
|
||||
return m_vertex0;
|
||||
}
|
||||
|
||||
int getVertex1() const
|
||||
{
|
||||
return m_vertex1;
|
||||
}
|
||||
|
||||
float getLinkStrength() const
|
||||
{
|
||||
return m_linkStrength;
|
||||
}
|
||||
|
||||
float getLinkLinearStiffness() const
|
||||
{
|
||||
return m_linkLinearStiffness;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
|
||||
btAlignedObjectArray< LinkNodePair > m_links; // Vertex pair for the link
|
||||
btAlignedObjectArray< float > m_linkStrength; // Strength of each link
|
||||
// (inverseMassA + inverseMassB)/ linear stiffness coefficient
|
||||
btAlignedObjectArray< float > m_linksMassLSC;
|
||||
btAlignedObjectArray< float > m_linksRestLengthSquared;
|
||||
// Current vector length of link
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_linksCLength;
|
||||
// 1/(current length * current length * massLSC)
|
||||
btAlignedObjectArray< float > m_linksLengthRatio;
|
||||
btAlignedObjectArray< float > m_linksRestLength;
|
||||
btAlignedObjectArray< float > m_linksMaterialLinearStiffnessCoefficient;
|
||||
|
||||
public:
|
||||
btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyLinkData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_links.resize(0);
|
||||
m_linkStrength.resize(0);
|
||||
m_linksMassLSC.resize(0);
|
||||
m_linksRestLengthSquared.resize(0);
|
||||
m_linksLengthRatio.resize(0);
|
||||
m_linksRestLength.resize(0);
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize(0);
|
||||
}
|
||||
|
||||
int getNumLinks()
|
||||
{
|
||||
return m_links.size();
|
||||
}
|
||||
|
||||
/** Allocate enough space in all link-related arrays to fit numLinks links */
|
||||
virtual void createLinks( int numLinks )
|
||||
{
|
||||
int previousSize = m_links.size();
|
||||
int newSize = previousSize + numLinks;
|
||||
|
||||
// Resize all the arrays that store link data
|
||||
m_links.resize( newSize );
|
||||
m_linkStrength.resize( newSize );
|
||||
m_linksMassLSC.resize( newSize );
|
||||
m_linksRestLengthSquared.resize( newSize );
|
||||
m_linksCLength.resize( newSize );
|
||||
m_linksLengthRatio.resize( newSize );
|
||||
m_linksRestLength.resize( newSize );
|
||||
m_linksMaterialLinearStiffnessCoefficient.resize( newSize );
|
||||
}
|
||||
|
||||
/** Insert the link described into the correct data structures assuming space has already been allocated by a call to createLinks */
|
||||
virtual void setLinkAt( const LinkDescription &link, int linkIndex )
|
||||
{
|
||||
m_links[linkIndex] = link.getVertexPair();
|
||||
m_linkStrength[linkIndex] = link.getLinkStrength();
|
||||
m_linksMassLSC[linkIndex] = 0.f;
|
||||
m_linksRestLengthSquared[linkIndex] = 0.f;
|
||||
m_linksCLength[linkIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_linksLengthRatio[linkIndex] = 0.f;
|
||||
m_linksRestLength[linkIndex] = 0.f;
|
||||
m_linksMaterialLinearStiffnessCoefficient[linkIndex] = link.getLinkLinearStiffness();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return reference to the vertex index pair for link linkIndex as stored on the host.
|
||||
*/
|
||||
LinkNodePair &getVertexPair( int linkIndex )
|
||||
{
|
||||
return m_links[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to strength of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getStrength( int linkIndex )
|
||||
{
|
||||
return m_linkStrength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the strength of the link corrected for link sorting.
|
||||
* This is important if we are using data on an accelerator which has the data sorted in some fashion.
|
||||
*/
|
||||
virtual float &getStrengthCorrected( int linkIndex )
|
||||
{
|
||||
return getStrength( linkIndex );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the rest length of link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLength( int linkIndex )
|
||||
{
|
||||
return m_linksRestLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to linear stiffness coefficient for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinearStiffnessCoefficient( int linkIndex )
|
||||
{
|
||||
return m_linksMaterialLinearStiffnessCoefficient[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to the MassLSC value for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getMassLSC( int linkIndex )
|
||||
{
|
||||
return m_linksMassLSC[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to rest length squared for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getRestLengthSquared( int linkIndex )
|
||||
{
|
||||
return m_linksRestLengthSquared[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return reference to current length of link linkIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getCurrentLength( int linkIndex )
|
||||
{
|
||||
return m_linksCLength[linkIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the link length ratio from for link linkIndex as stored on the host.
|
||||
*/
|
||||
float &getLinkLengthRatio( int linkIndex )
|
||||
{
|
||||
return m_linksLengthRatio[linkIndex];
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Wrapper for vertex data information.
|
||||
* By wrapping it like this we stand a good chance of being able to optimise for storage format easily.
|
||||
* It should also help us make sure all the data structures remain consistent.
|
||||
*/
|
||||
class btSoftBodyVertexData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class describing a vertex for input into the system.
|
||||
*/
|
||||
class VertexDescription
|
||||
{
|
||||
private:
|
||||
Vectormath::Aos::Point3 m_position;
|
||||
/** Inverse mass. If this is 0f then the mass was 0 because that simplifies calculations. */
|
||||
float m_inverseMass;
|
||||
|
||||
public:
|
||||
VertexDescription()
|
||||
{
|
||||
m_position = Vectormath::Aos::Point3( 0.f, 0.f, 0.f );
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
VertexDescription( const Vectormath::Aos::Point3 &position, float mass )
|
||||
{
|
||||
m_position = position;
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
void setPosition( const Vectormath::Aos::Point3 &position )
|
||||
{
|
||||
m_position = position;
|
||||
}
|
||||
|
||||
void setInverseMass( float inverseMass )
|
||||
{
|
||||
m_inverseMass = inverseMass;
|
||||
}
|
||||
|
||||
void setMass( float mass )
|
||||
{
|
||||
if( mass > 0.f )
|
||||
m_inverseMass = 1.0f/mass;
|
||||
else
|
||||
m_inverseMass = 0.f;
|
||||
}
|
||||
|
||||
Vectormath::Aos::Point3 getPosition() const
|
||||
{
|
||||
return m_position;
|
||||
}
|
||||
|
||||
float getInverseMass() const
|
||||
{
|
||||
return m_inverseMass;
|
||||
}
|
||||
|
||||
float getMass() const
|
||||
{
|
||||
if( m_inverseMass == 0.f )
|
||||
return 0.f;
|
||||
else
|
||||
return 1.0f/m_inverseMass;
|
||||
}
|
||||
};
|
||||
protected:
|
||||
|
||||
// identifier for the individual cloth
|
||||
// For the CPU we don't really need this as we can grab the cloths and iterate over only their vertices
|
||||
// For a parallel accelerator knowing on a per-vertex basis which cloth we're part of will help for obtaining
|
||||
// per-cloth data
|
||||
// For sorting etc it might also be helpful to be able to use in-array data such as this.
|
||||
btAlignedObjectArray< int > m_clothIdentifier;
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > m_vertexPreviousPosition; // vertex positions
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexVelocity; // Velocity
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexForceAccumulator; // Force accumulator
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_vertexNormal; // Normals
|
||||
btAlignedObjectArray< float > m_vertexInverseMass; // Inverse mass
|
||||
btAlignedObjectArray< float > m_vertexArea; // Area controlled by the vertex
|
||||
btAlignedObjectArray< int > m_vertexTriangleCount; // Number of triangles touching this vertex
|
||||
|
||||
public:
|
||||
btSoftBodyVertexData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyVertexData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_clothIdentifier.resize(0);
|
||||
m_vertexPosition.resize(0);
|
||||
m_vertexPreviousPosition.resize(0);
|
||||
m_vertexVelocity.resize(0);
|
||||
m_vertexForceAccumulator.resize(0);
|
||||
m_vertexNormal.resize(0);
|
||||
m_vertexInverseMass.resize(0);
|
||||
m_vertexArea.resize(0);
|
||||
m_vertexTriangleCount.resize(0);
|
||||
}
|
||||
|
||||
int getNumVertices()
|
||||
{
|
||||
return m_vertexPosition.size();
|
||||
}
|
||||
|
||||
int getClothIdentifier( int vertexIndex )
|
||||
{
|
||||
return m_clothIdentifier[vertexIndex];
|
||||
}
|
||||
|
||||
void setVertexAt( const VertexDescription &vertex, int vertexIndex )
|
||||
{
|
||||
m_vertexPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexPreviousPosition[vertexIndex] = vertex.getPosition();
|
||||
m_vertexVelocity[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexForceAccumulator[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexNormal[vertexIndex] = Vectormath::Aos::Vector3(0.f, 0.f, 0.f);
|
||||
m_vertexInverseMass[vertexIndex] = vertex.getInverseMass();
|
||||
m_vertexArea[vertexIndex] = 0.f;
|
||||
m_vertexTriangleCount[vertexIndex] = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create numVertices new vertices for cloth clothIdentifier
|
||||
* maxVertices allows a buffer zone of extra vertices for alignment or tearing reasons.
|
||||
*/
|
||||
void createVertices( int numVertices, int clothIdentifier, int maxVertices = 0 )
|
||||
{
|
||||
int previousSize = m_vertexPosition.size();
|
||||
if( maxVertices == 0 )
|
||||
maxVertices = numVertices;
|
||||
int newSize = previousSize + maxVertices;
|
||||
|
||||
// Resize all the arrays that store vertex data
|
||||
m_clothIdentifier.resize( newSize );
|
||||
m_vertexPosition.resize( newSize );
|
||||
m_vertexPreviousPosition.resize( newSize );
|
||||
m_vertexVelocity.resize( newSize );
|
||||
m_vertexForceAccumulator.resize( newSize );
|
||||
m_vertexNormal.resize( newSize );
|
||||
m_vertexInverseMass.resize( newSize );
|
||||
m_vertexArea.resize( newSize );
|
||||
m_vertexTriangleCount.resize( newSize );
|
||||
|
||||
for( int vertexIndex = previousSize; vertexIndex < newSize; ++vertexIndex )
|
||||
m_clothIdentifier[vertexIndex] = clothIdentifier;
|
||||
for( int vertexIndex = (previousSize + numVertices); vertexIndex < newSize; ++vertexIndex )
|
||||
m_clothIdentifier[vertexIndex] = -1;
|
||||
}
|
||||
|
||||
// Get and set methods in header so they can be inlined
|
||||
|
||||
/**
|
||||
* Return a reference to the position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPosition[vertexIndex];
|
||||
}
|
||||
|
||||
Vectormath::Aos::Point3 getPosition( int vertexIndex ) const
|
||||
{
|
||||
return m_vertexPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the previous position of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Point3 &getPreviousPosition( int vertexIndex )
|
||||
{
|
||||
return m_vertexPreviousPosition[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the velocity of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getVelocity( int vertexIndex )
|
||||
{
|
||||
return m_vertexVelocity[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the force accumulator of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getForceAccumulator( int vertexIndex )
|
||||
{
|
||||
return m_vertexForceAccumulator[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the normal of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int vertexIndex )
|
||||
{
|
||||
return m_vertexNormal[vertexIndex];
|
||||
}
|
||||
|
||||
Vectormath::Aos::Vector3 getNormal( int vertexIndex ) const
|
||||
{
|
||||
return m_vertexNormal[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a reference to the inverse mass of vertex vertexIndex as stored on the host.
|
||||
*/
|
||||
float &getInverseMass( int vertexIndex )
|
||||
{
|
||||
return m_vertexInverseMass[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the area controlled by this vertex.
|
||||
*/
|
||||
float &getArea( int vertexIndex )
|
||||
{
|
||||
return m_vertexArea[vertexIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the array of how many triangles touch each vertex.
|
||||
*/
|
||||
int &getTriangleCount( int vertexIndex )
|
||||
{
|
||||
return m_vertexTriangleCount[vertexIndex];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data to host memory from the accelerator if bCopy is false.
|
||||
* If bCopy is true, copy data to host memory from the accelerator so that data
|
||||
* won't be moved to accelerator when moveToAccelerator() is called next time.
|
||||
* If bCopyMinimum is true, only vertex position and normal are copied.
|
||||
* bCopyMinimum will be meaningful only if bCopy is true.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator(bool bCopy = false, bool bCopyMinimum = true)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
btAlignedObjectArray< Vectormath::Aos::Point3 > &getVertexPositions()
|
||||
{
|
||||
return m_vertexPosition;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
class btSoftBodyTriangleData
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* Class representing a triangle as a set of three indices into the
|
||||
* vertex array.
|
||||
*/
|
||||
class TriangleNodeSet
|
||||
{
|
||||
public:
|
||||
int vertex0;
|
||||
int vertex1;
|
||||
int vertex2;
|
||||
int _padding;
|
||||
|
||||
TriangleNodeSet( )
|
||||
{
|
||||
vertex0 = 0;
|
||||
vertex1 = 0;
|
||||
vertex2 = 0;
|
||||
_padding = -1;
|
||||
}
|
||||
|
||||
TriangleNodeSet( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
vertex0 = newVertex0;
|
||||
vertex1 = newVertex1;
|
||||
vertex2 = newVertex2;
|
||||
}
|
||||
};
|
||||
|
||||
class TriangleDescription
|
||||
{
|
||||
protected:
|
||||
int m_vertex0;
|
||||
int m_vertex1;
|
||||
int m_vertex2;
|
||||
|
||||
public:
|
||||
TriangleDescription()
|
||||
{
|
||||
m_vertex0 = 0;
|
||||
m_vertex1 = 0;
|
||||
m_vertex2 = 0;
|
||||
}
|
||||
|
||||
TriangleDescription( int newVertex0, int newVertex1, int newVertex2 )
|
||||
{
|
||||
m_vertex0 = newVertex0;
|
||||
m_vertex1 = newVertex1;
|
||||
m_vertex2 = newVertex2;
|
||||
}
|
||||
|
||||
TriangleNodeSet getVertexSet() const
|
||||
{
|
||||
btSoftBodyTriangleData::TriangleNodeSet nodes;
|
||||
nodes.vertex0 = m_vertex0;
|
||||
nodes.vertex1 = m_vertex1;
|
||||
nodes.vertex2 = m_vertex2;
|
||||
return nodes;
|
||||
}
|
||||
};
|
||||
|
||||
protected:
|
||||
// NOTE:
|
||||
// Vertex reference data is stored relative to global array, not relative to individual cloth.
|
||||
// Values must be correct if being passed into single-cloth VBOs or when migrating from one solver
|
||||
// to another.
|
||||
btAlignedObjectArray< TriangleNodeSet > m_vertexIndices;
|
||||
btAlignedObjectArray< float > m_area;
|
||||
btAlignedObjectArray< Vectormath::Aos::Vector3 > m_normal;
|
||||
|
||||
public:
|
||||
btSoftBodyTriangleData()
|
||||
{
|
||||
}
|
||||
|
||||
virtual ~btSoftBodyTriangleData()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
virtual void clear()
|
||||
{
|
||||
m_vertexIndices.resize(0);
|
||||
m_area.resize(0);
|
||||
m_normal.resize(0);
|
||||
}
|
||||
|
||||
int getNumTriangles()
|
||||
{
|
||||
return m_vertexIndices.size();
|
||||
}
|
||||
|
||||
virtual void setTriangleAt( const TriangleDescription &triangle, int triangleIndex )
|
||||
{
|
||||
m_vertexIndices[triangleIndex] = triangle.getVertexSet();
|
||||
}
|
||||
|
||||
virtual void createTriangles( int numTriangles )
|
||||
{
|
||||
int previousSize = m_vertexIndices.size();
|
||||
int newSize = previousSize + numTriangles;
|
||||
|
||||
// Resize all the arrays that store triangle data
|
||||
m_vertexIndices.resize( newSize );
|
||||
m_area.resize( newSize );
|
||||
m_normal.resize( newSize );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the vertex index set for triangle triangleIndex as stored on the host.
|
||||
*/
|
||||
const TriangleNodeSet &getVertexSet( int triangleIndex )
|
||||
{
|
||||
return m_vertexIndices[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the triangle area.
|
||||
*/
|
||||
float &getTriangleArea( int triangleIndex )
|
||||
{
|
||||
return m_area[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get access to the normal vector for this triangle.
|
||||
*/
|
||||
Vectormath::Aos::Vector3 &getNormal( int triangleIndex )
|
||||
{
|
||||
return m_normal[triangleIndex];
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if data is on the accelerator.
|
||||
* The CPU version of this class will return true here because
|
||||
* the CPU is the same as the accelerator.
|
||||
*/
|
||||
virtual bool onAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory to the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveToAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Move data from host memory from the accelerator.
|
||||
* The CPU version will always return that it has moved it.
|
||||
*/
|
||||
virtual bool moveFromAccelerator()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
#endif // #ifndef BT_SOFT_BODY_SOLVER_DATA_H
|
||||
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/*
|
||||
Copyright (C) 2009 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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 __HEAP_MANAGER_H__
|
||||
#define __HEAP_MANAGER_H__
|
||||
|
||||
#ifdef __SPU__
|
||||
#define HEAP_STACK_SIZE 32
|
||||
#else
|
||||
#define HEAP_STACK_SIZE 64
|
||||
#endif
|
||||
|
||||
#define MIN_ALLOC_SIZE 16
|
||||
|
||||
|
||||
class HeapManager
|
||||
{
|
||||
private:
|
||||
ATTRIBUTE_ALIGNED16(unsigned char *mHeap);
|
||||
ATTRIBUTE_ALIGNED16(unsigned int mHeapBytes);
|
||||
ATTRIBUTE_ALIGNED16(unsigned char *mPoolStack[HEAP_STACK_SIZE]);
|
||||
ATTRIBUTE_ALIGNED16(unsigned int mCurStack);
|
||||
|
||||
public:
|
||||
enum {ALIGN16,ALIGN128};
|
||||
|
||||
HeapManager(unsigned char *buf,int bytes)
|
||||
{
|
||||
mHeap = buf;
|
||||
mHeapBytes = bytes;
|
||||
clear();
|
||||
}
|
||||
|
||||
~HeapManager()
|
||||
{
|
||||
}
|
||||
|
||||
int getAllocated()
|
||||
{
|
||||
return (int)(mPoolStack[mCurStack]-mHeap);
|
||||
}
|
||||
|
||||
int getRest()
|
||||
{
|
||||
return mHeapBytes-getAllocated();
|
||||
}
|
||||
|
||||
void *allocate(size_t bytes,int alignment = ALIGN16)
|
||||
{
|
||||
if(bytes <= 0) bytes = MIN_ALLOC_SIZE;
|
||||
btAssert(mCurStack < (HEAP_STACK_SIZE-1));
|
||||
|
||||
|
||||
#if defined(_WIN64) || defined(__LP64__) || defined(__x86_64__)
|
||||
unsigned long long p = (unsigned long long )mPoolStack[mCurStack];
|
||||
if(alignment == ALIGN128) {
|
||||
p = ((p+127) & 0xffffffffffffff80);
|
||||
bytes = (bytes+127) & 0xffffffffffffff80;
|
||||
}
|
||||
else {
|
||||
bytes = (bytes+15) & 0xfffffffffffffff0;
|
||||
}
|
||||
|
||||
btAssert(bytes <=(mHeapBytes-(p-(unsigned long long )mHeap)) );
|
||||
|
||||
#else
|
||||
unsigned long p = (unsigned long )mPoolStack[mCurStack];
|
||||
if(alignment == ALIGN128) {
|
||||
p = ((p+127) & 0xffffff80);
|
||||
bytes = (bytes+127) & 0xffffff80;
|
||||
}
|
||||
else {
|
||||
bytes = (bytes+15) & 0xfffffff0;
|
||||
}
|
||||
btAssert(bytes <=(mHeapBytes-(p-(unsigned long)mHeap)) );
|
||||
#endif
|
||||
unsigned char * bla = (unsigned char *)(p + bytes);
|
||||
mPoolStack[++mCurStack] = bla;
|
||||
return (void*)p;
|
||||
}
|
||||
|
||||
void deallocate(void *p)
|
||||
{
|
||||
(void) p;
|
||||
mCurStack--;
|
||||
}
|
||||
|
||||
void clear()
|
||||
{
|
||||
mPoolStack[0] = mHeap;
|
||||
mCurStack = 0;
|
||||
}
|
||||
|
||||
// void printStack()
|
||||
// {
|
||||
// for(unsigned int i=0;i<=mCurStack;i++) {
|
||||
// PRINTF("memStack %2d 0x%x\n",i,(uint32_t)mPoolStack[i]);
|
||||
// }
|
||||
// }
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
#ifndef TYPE_DEFINITIONS_H
|
||||
#define TYPE_DEFINITIONS_H
|
||||
|
||||
///This file provides some platform/compiler checks for common definitions
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "LinearMath/btMinMax.h"
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
typedef union
|
||||
{
|
||||
unsigned int u;
|
||||
void *p;
|
||||
} addr64;
|
||||
|
||||
#define USE_WIN32_THREADING 1
|
||||
|
||||
#if defined(__MINGW32__) || defined(__CYGWIN__) || (defined (_MSC_VER) && _MSC_VER < 1300)
|
||||
#else
|
||||
#endif //__MINGW32__
|
||||
|
||||
typedef unsigned char uint8_t;
|
||||
#ifndef __PHYSICS_COMMON_H__
|
||||
#ifndef __PFX_COMMON_H__
|
||||
#ifndef __BT_SKIP_UINT64_H
|
||||
typedef unsigned long int uint64_t;
|
||||
#endif //__BT_SKIP_UINT64_H
|
||||
#endif //__PFX_COMMON_H__
|
||||
typedef unsigned int uint32_t;
|
||||
#endif //__PHYSICS_COMMON_H__
|
||||
typedef unsigned short uint16_t;
|
||||
|
||||
#include <malloc.h>
|
||||
#define memalign(alignment, size) malloc(size);
|
||||
|
||||
#include <string.h> //memcpy
|
||||
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#define spu_printf printf
|
||||
|
||||
#else
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h> //for memcpy
|
||||
|
||||
#if defined (__CELLOS_LV2__)
|
||||
// Playstation 3 Cell SDK
|
||||
#include <spu_printf.h>
|
||||
|
||||
#else
|
||||
// posix system
|
||||
|
||||
#define USE_PTHREADS (1)
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
#include <stdio.h>
|
||||
#define spu_printf printf
|
||||
#define DWORD unsigned int
|
||||
typedef union
|
||||
{
|
||||
unsigned long long ull;
|
||||
unsigned int ui[2];
|
||||
void *p;
|
||||
} addr64;
|
||||
#endif // USE_LIBSPE2
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __SPU__
|
||||
#include <stdio.h>
|
||||
#define printf spu_printf
|
||||
#endif
|
||||
|
||||
/* Included here because we need uint*_t typedefs */
|
||||
#include "PpuAddressSpace.h"
|
||||
|
||||
#endif //TYPE_DEFINITIONS_H
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,137 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
#ifdef USE_PTHREADS //platform specific defines are defined in PlatformDefinitions.h
|
||||
#ifndef _XOPEN_SOURCE
|
||||
#define _XOPEN_SOURCE 600 //for definition of pthread_barrier_t, see http://pages.cs.wisc.edu/~travitch/pthreads_primer.html
|
||||
#endif //_XOPEN_SOURCE
|
||||
#include <pthread.h>
|
||||
#include <semaphore.h>
|
||||
|
||||
#ifndef POSIX_THREAD_SUPPORT_H
|
||||
#define POSIX_THREAD_SUPPORT_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btThreadSupportInterface.h"
|
||||
|
||||
|
||||
typedef void (*PosixThreadFunc)(void* userPtr,void* lsMemory);
|
||||
typedef void* (*PosixlsMemorySetupFunc)();
|
||||
|
||||
// PosixThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
|
||||
class PosixThreadSupport : public btThreadSupportInterface
|
||||
{
|
||||
public:
|
||||
typedef enum sStatus {
|
||||
STATUS_BUSY,
|
||||
STATUS_READY,
|
||||
STATUS_FINISHED
|
||||
} Status;
|
||||
|
||||
// placeholder, until libspe2 support is there
|
||||
struct btSpuStatus
|
||||
{
|
||||
uint32_t m_taskId;
|
||||
uint32_t m_commandId;
|
||||
uint32_t m_status;
|
||||
|
||||
PosixThreadFunc m_userThreadFunc;
|
||||
void* m_userPtr; //for taskDesc etc
|
||||
void* m_lsMemory; //initialized using PosixLocalStoreMemorySetupFunc
|
||||
|
||||
pthread_t thread;
|
||||
sem_t* startSemaphore;
|
||||
|
||||
unsigned long threadUsed;
|
||||
};
|
||||
private:
|
||||
|
||||
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
|
||||
public:
|
||||
///Setup and initialize SPU/CELL/Libspe2
|
||||
|
||||
|
||||
|
||||
struct ThreadConstructionInfo
|
||||
{
|
||||
ThreadConstructionInfo(char* uniqueName,
|
||||
PosixThreadFunc userThreadFunc,
|
||||
PosixlsMemorySetupFunc lsMemoryFunc,
|
||||
int numThreads=1,
|
||||
int threadStackSize=65535
|
||||
)
|
||||
:m_uniqueName(uniqueName),
|
||||
m_userThreadFunc(userThreadFunc),
|
||||
m_lsMemoryFunc(lsMemoryFunc),
|
||||
m_numThreads(numThreads),
|
||||
m_threadStackSize(threadStackSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* m_uniqueName;
|
||||
PosixThreadFunc m_userThreadFunc;
|
||||
PosixlsMemorySetupFunc m_lsMemoryFunc;
|
||||
int m_numThreads;
|
||||
int m_threadStackSize;
|
||||
|
||||
};
|
||||
|
||||
PosixThreadSupport(ThreadConstructionInfo& threadConstructionInfo);
|
||||
|
||||
///cleanup/shutdown Libspe2
|
||||
virtual ~PosixThreadSupport();
|
||||
|
||||
void startThreads(ThreadConstructionInfo& threadInfo);
|
||||
|
||||
|
||||
///send messages to SPUs
|
||||
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1);
|
||||
|
||||
///check for messages from SPUs
|
||||
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
|
||||
|
||||
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
virtual void startSPU();
|
||||
|
||||
///tell the task scheduler we are done with the SPU tasks
|
||||
virtual void stopSPU();
|
||||
|
||||
virtual void setNumTasks(int numTasks) {}
|
||||
|
||||
virtual int getNumTasks() const
|
||||
{
|
||||
return m_activeSpuStatus.size();
|
||||
}
|
||||
|
||||
virtual btBarrier* createBarrier();
|
||||
|
||||
virtual btCriticalSection* createCriticalSection();
|
||||
|
||||
virtual void* getThreadLocalMemory(int taskId)
|
||||
{
|
||||
return m_activeSpuStatus[taskId].m_lsMemory;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif // POSIX_THREAD_SUPPORT_H
|
||||
|
||||
#endif // USE_PTHREADS
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2010 Erwin Coumans http://bulletphysics.org
|
||||
|
||||
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 __PPU_ADDRESS_SPACE_H
|
||||
#define __PPU_ADDRESS_SPACE_H
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
//stop those casting warnings until we have a better solution for ppu_address_t / void* / uint64 conversions
|
||||
#pragma warning (disable: 4311)
|
||||
#pragma warning (disable: 4312)
|
||||
#endif //_WIN32
|
||||
|
||||
|
||||
#if defined(_WIN64)
|
||||
typedef unsigned __int64 ppu_address_t;
|
||||
#elif defined(__LP64__) || defined(__x86_64__)
|
||||
typedef uint64_t ppu_address_t;
|
||||
#else
|
||||
typedef uint32_t ppu_address_t;
|
||||
#endif //defined(_WIN64)
|
||||
|
||||
#endif //__PPU_ADDRESS_SPACE_H
|
||||
|
||||
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
|
||||
#ifndef SEQUENTIAL_THREAD_SUPPORT_H
|
||||
#define SEQUENTIAL_THREAD_SUPPORT_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btThreadSupportInterface.h"
|
||||
|
||||
typedef void (*SequentialThreadFunc)(void* userPtr,void* lsMemory);
|
||||
typedef void* (*SequentiallsMemorySetupFunc)();
|
||||
|
||||
|
||||
|
||||
///The SequentialThreadSupport is a portable non-parallel implementation of the btThreadSupportInterface
|
||||
///This is useful for debugging and porting SPU Tasks to other platforms.
|
||||
class SequentialThreadSupport : public btThreadSupportInterface
|
||||
{
|
||||
public:
|
||||
struct btSpuStatus
|
||||
{
|
||||
uint32_t m_taskId;
|
||||
uint32_t m_commandId;
|
||||
uint32_t m_status;
|
||||
|
||||
SequentialThreadFunc m_userThreadFunc;
|
||||
|
||||
void* m_userPtr; //for taskDesc etc
|
||||
void* m_lsMemory; //initialized using SequentiallsMemorySetupFunc
|
||||
};
|
||||
private:
|
||||
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
|
||||
btAlignedObjectArray<void*> m_completeHandles;
|
||||
public:
|
||||
struct SequentialThreadConstructionInfo
|
||||
{
|
||||
SequentialThreadConstructionInfo (char* uniqueName,
|
||||
SequentialThreadFunc userThreadFunc,
|
||||
SequentiallsMemorySetupFunc lsMemoryFunc
|
||||
)
|
||||
:m_uniqueName(uniqueName),
|
||||
m_userThreadFunc(userThreadFunc),
|
||||
m_lsMemoryFunc(lsMemoryFunc)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* m_uniqueName;
|
||||
SequentialThreadFunc m_userThreadFunc;
|
||||
SequentiallsMemorySetupFunc m_lsMemoryFunc;
|
||||
};
|
||||
|
||||
SequentialThreadSupport(SequentialThreadConstructionInfo& threadConstructionInfo);
|
||||
virtual ~SequentialThreadSupport();
|
||||
void startThreads(SequentialThreadConstructionInfo& threadInfo);
|
||||
///send messages to SPUs
|
||||
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1);
|
||||
///check for messages from SPUs
|
||||
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
|
||||
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
virtual void startSPU();
|
||||
///tell the task scheduler we are done with the SPU tasks
|
||||
virtual void stopSPU();
|
||||
|
||||
virtual void setNumTasks(int numTasks);
|
||||
|
||||
virtual int getNumTasks() const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
virtual btBarrier* createBarrier();
|
||||
|
||||
virtual btCriticalSection* createCriticalSection();
|
||||
|
||||
|
||||
};
|
||||
|
||||
#endif //SEQUENTIAL_THREAD_SUPPORT_H
|
||||
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_COLLISION_OBJECT_WRAPPER_H
|
||||
#define SPU_COLLISION_OBJECT_WRAPPER_H
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
|
||||
ATTRIBUTE_ALIGNED16(class) SpuCollisionObjectWrapper
|
||||
{
|
||||
protected:
|
||||
int m_shapeType;
|
||||
float m_margin;
|
||||
ppu_address_t m_collisionObjectPtr;
|
||||
|
||||
public:
|
||||
SpuCollisionObjectWrapper ();
|
||||
|
||||
SpuCollisionObjectWrapper (const btCollisionObject* collisionObject);
|
||||
|
||||
int getShapeType () const;
|
||||
float getCollisionMargin () const;
|
||||
ppu_address_t getCollisionObjectPtr () const;
|
||||
};
|
||||
|
||||
|
||||
#endif //SPU_COLLISION_OBJECT_WRAPPER_H
|
||||
|
|
@ -0,0 +1,163 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_COLLISION_TASK_PROCESS_H
|
||||
#define SPU_COLLISION_TASK_PROCESS_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h" // for definitions processCollisionTask and createCollisionLocalStoreMemory
|
||||
|
||||
#include "btThreadSupportInterface.h"
|
||||
|
||||
|
||||
//#include "SPUAssert.h"
|
||||
#include <string.h>
|
||||
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionObject.h"
|
||||
#include "BulletCollision/CollisionShapes/btCollisionShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
|
||||
#define DEBUG_SpuCollisionTaskProcess 1
|
||||
|
||||
|
||||
#define CMD_GATHER_AND_PROCESS_PAIRLIST 1
|
||||
|
||||
class btCollisionObject;
|
||||
class btPersistentManifold;
|
||||
class btDispatcher;
|
||||
|
||||
|
||||
/////Task Description for SPU collision detection
|
||||
//struct SpuGatherAndProcessPairsTaskDesc
|
||||
//{
|
||||
// uint64_t inPtr;//m_pairArrayPtr;
|
||||
// //mutex variable
|
||||
// uint32_t m_someMutexVariableInMainMemory;
|
||||
//
|
||||
// uint64_t m_dispatcher;
|
||||
//
|
||||
// uint32_t numOnLastPage;
|
||||
//
|
||||
// uint16_t numPages;
|
||||
// uint16_t taskId;
|
||||
//
|
||||
// struct CollisionTask_LocalStoreMemory* m_lsMemory;
|
||||
//}
|
||||
//
|
||||
//#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2)
|
||||
//__attribute__ ((aligned (16)))
|
||||
//#endif
|
||||
//;
|
||||
|
||||
|
||||
///MidphaseWorkUnitInput stores individual primitive versus mesh collision detection input, to be processed by the SPU.
|
||||
ATTRIBUTE_ALIGNED16(struct) SpuGatherAndProcessWorkUnitInput
|
||||
{
|
||||
uint64_t m_pairArrayPtr;
|
||||
int m_startIndex;
|
||||
int m_endIndex;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
/// SpuCollisionTaskProcess handles SPU processing of collision pairs.
|
||||
/// Maintains a set of task buffers.
|
||||
/// When the task is full, the task is issued for SPUs to process. Contact output goes into btPersistentManifold
|
||||
/// associated with each task.
|
||||
/// When PPU issues a task, it will look for completed task buffers
|
||||
/// PPU will do postprocessing, dependent on workunit output (not likely)
|
||||
class SpuCollisionTaskProcess
|
||||
{
|
||||
|
||||
unsigned char *m_workUnitTaskBuffers;
|
||||
|
||||
|
||||
// track task buffers that are being used, and total busy tasks
|
||||
btAlignedObjectArray<bool> m_taskBusy;
|
||||
btAlignedObjectArray<SpuGatherAndProcessPairsTaskDesc> m_spuGatherTaskDesc;
|
||||
|
||||
class btThreadSupportInterface* m_threadInterface;
|
||||
|
||||
unsigned int m_maxNumOutstandingTasks;
|
||||
|
||||
unsigned int m_numBusyTasks;
|
||||
|
||||
// the current task and the current entry to insert a new work unit
|
||||
unsigned int m_currentTask;
|
||||
unsigned int m_currentPage;
|
||||
unsigned int m_currentPageEntry;
|
||||
|
||||
bool m_useEpa;
|
||||
|
||||
#ifdef DEBUG_SpuCollisionTaskProcess
|
||||
bool m_initialized;
|
||||
#endif
|
||||
void issueTask2();
|
||||
//void postProcess(unsigned int taskId, int outputSize);
|
||||
|
||||
public:
|
||||
SpuCollisionTaskProcess(btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks);
|
||||
|
||||
~SpuCollisionTaskProcess();
|
||||
|
||||
///call initialize in the beginning of the frame, before addCollisionPairToTask
|
||||
void initialize2(bool useEpa = false);
|
||||
|
||||
///batch up additional work to a current task for SPU processing. When batch is full, it issues the task.
|
||||
void addWorkToTask(void* pairArrayPtr,int startIndex,int endIndex);
|
||||
|
||||
///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished
|
||||
void flush2();
|
||||
|
||||
/// set the maximum number of SPU tasks allocated
|
||||
void setNumTasks(int maxNumTasks);
|
||||
|
||||
int getNumTasks() const
|
||||
{
|
||||
return m_maxNumOutstandingTasks;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
|
||||
#define MIDPHASE_TASK_PTR(task) (&m_workUnitTaskBuffers[0] + MIDPHASE_WORKUNIT_TASK_SIZE*task)
|
||||
#define MIDPHASE_ENTRY_PTR(task,page,entry) (MIDPHASE_TASK_PTR(task) + MIDPHASE_WORKUNIT_PAGE_SIZE*page + sizeof(SpuGatherAndProcessWorkUnitInput)*entry)
|
||||
#define MIDPHASE_OUTPUT_PTR(task) (&m_contactOutputBuffers[0] + MIDPHASE_MAX_CONTACT_BUFFER_SIZE*task)
|
||||
#define MIDPHASE_TREENODES_PTR(task) (&m_complexShapeBuffers[0] + MIDPHASE_COMPLEX_SHAPE_BUFFER_SIZE*task)
|
||||
|
||||
|
||||
#define MIDPHASE_WORKUNIT_PAGE_SIZE (16)
|
||||
//#define MIDPHASE_WORKUNIT_PAGE_SIZE (128)
|
||||
|
||||
#define MIDPHASE_NUM_WORKUNIT_PAGES 1
|
||||
#define MIDPHASE_WORKUNIT_TASK_SIZE (MIDPHASE_WORKUNIT_PAGE_SIZE*MIDPHASE_NUM_WORKUNIT_PAGES)
|
||||
#define MIDPHASE_NUM_WORKUNITS_PER_PAGE (MIDPHASE_WORKUNIT_PAGE_SIZE / sizeof(SpuGatherAndProcessWorkUnitInput))
|
||||
#define MIDPHASE_NUM_WORKUNITS_PER_TASK (MIDPHASE_NUM_WORKUNITS_PER_PAGE*MIDPHASE_NUM_WORKUNIT_PAGES)
|
||||
|
||||
|
||||
#endif // SPU_COLLISION_TASK_PROCESS_H
|
||||
|
||||
|
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H
|
||||
#define SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btCollisionAlgorithm.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionCreateFunc.h"
|
||||
#include "BulletCollision/BroadphaseCollision/btDispatcher.h"
|
||||
#include "LinearMath/btTransformUtil.h"
|
||||
|
||||
class btPersistentManifold;
|
||||
|
||||
//#define USE_SEPDISTANCE_UTIL 1
|
||||
|
||||
/// SpuContactManifoldCollisionAlgorithm provides contact manifold and should be processed on SPU.
|
||||
ATTRIBUTE_ALIGNED16(class) SpuContactManifoldCollisionAlgorithm : public btCollisionAlgorithm
|
||||
{
|
||||
btVector3 m_shapeDimensions0;
|
||||
btVector3 m_shapeDimensions1;
|
||||
btPersistentManifold* m_manifoldPtr;
|
||||
int m_shapeType0;
|
||||
int m_shapeType1;
|
||||
float m_collisionMargin0;
|
||||
float m_collisionMargin1;
|
||||
|
||||
btCollisionObject* m_collisionObject0;
|
||||
btCollisionObject* m_collisionObject1;
|
||||
|
||||
|
||||
|
||||
|
||||
public:
|
||||
|
||||
virtual void processCollision (btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
virtual btScalar calculateTimeOfImpact(btCollisionObject* body0,btCollisionObject* body1,const btDispatcherInfo& dispatchInfo,btManifoldResult* resultOut);
|
||||
|
||||
|
||||
SpuContactManifoldCollisionAlgorithm(const btCollisionAlgorithmConstructionInfo& ci,btCollisionObject* body0,btCollisionObject* body1);
|
||||
#ifdef USE_SEPDISTANCE_UTIL
|
||||
btConvexSeparatingDistanceUtil m_sepDistance;
|
||||
#endif //USE_SEPDISTANCE_UTIL
|
||||
|
||||
virtual ~SpuContactManifoldCollisionAlgorithm();
|
||||
|
||||
virtual void getAllContactManifolds(btManifoldArray& manifoldArray)
|
||||
{
|
||||
if (m_manifoldPtr)
|
||||
manifoldArray.push_back(m_manifoldPtr);
|
||||
}
|
||||
|
||||
btPersistentManifold* getContactManifoldPtr()
|
||||
{
|
||||
return m_manifoldPtr;
|
||||
}
|
||||
|
||||
btCollisionObject* getCollisionObject0()
|
||||
{
|
||||
return m_collisionObject0;
|
||||
}
|
||||
|
||||
btCollisionObject* getCollisionObject1()
|
||||
{
|
||||
return m_collisionObject1;
|
||||
}
|
||||
|
||||
int getShapeType0() const
|
||||
{
|
||||
return m_shapeType0;
|
||||
}
|
||||
|
||||
int getShapeType1() const
|
||||
{
|
||||
return m_shapeType1;
|
||||
}
|
||||
float getCollisionMargin0() const
|
||||
{
|
||||
return m_collisionMargin0;
|
||||
}
|
||||
float getCollisionMargin1() const
|
||||
{
|
||||
return m_collisionMargin1;
|
||||
}
|
||||
|
||||
const btVector3& getShapeDimensions0() const
|
||||
{
|
||||
return m_shapeDimensions0;
|
||||
}
|
||||
|
||||
const btVector3& getShapeDimensions1() const
|
||||
{
|
||||
return m_shapeDimensions1;
|
||||
}
|
||||
|
||||
struct CreateFunc :public btCollisionAlgorithmCreateFunc
|
||||
{
|
||||
virtual btCollisionAlgorithm* CreateCollisionAlgorithm(btCollisionAlgorithmConstructionInfo& ci, btCollisionObject* body0,btCollisionObject* body1)
|
||||
{
|
||||
void* mem = ci.m_dispatcher1->allocateCollisionAlgorithm(sizeof(SpuContactManifoldCollisionAlgorithm));
|
||||
return new(mem) SpuContactManifoldCollisionAlgorithm(ci,body0,body1);
|
||||
}
|
||||
};
|
||||
|
||||
};
|
||||
|
||||
#endif //SPU_CONTACTMANIFOLD_COLLISION_ALGORITHM_H
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
#ifndef DOUBLE_BUFFER_H
|
||||
#define DOUBLE_BUFFER_H
|
||||
|
||||
#include "SpuFakeDma.h"
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
|
||||
///DoubleBuffer
|
||||
template<class T, int size>
|
||||
class DoubleBuffer
|
||||
{
|
||||
#if defined(__SPU__) || defined(USE_LIBSPE2)
|
||||
ATTRIBUTE_ALIGNED128( T m_buffer0[size] ) ;
|
||||
ATTRIBUTE_ALIGNED128( T m_buffer1[size] ) ;
|
||||
#else
|
||||
T m_buffer0[size];
|
||||
T m_buffer1[size];
|
||||
#endif
|
||||
|
||||
T *m_frontBuffer;
|
||||
T *m_backBuffer;
|
||||
|
||||
unsigned int m_dmaTag;
|
||||
bool m_dmaPending;
|
||||
public:
|
||||
bool isPending() const { return m_dmaPending;}
|
||||
DoubleBuffer();
|
||||
|
||||
void init ();
|
||||
|
||||
// dma get and put commands
|
||||
void backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag);
|
||||
void backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag);
|
||||
|
||||
// gets pointer to a buffer
|
||||
T *getFront();
|
||||
T *getBack();
|
||||
|
||||
// if back buffer dma was started, wait for it to complete
|
||||
// then move back to front and vice versa
|
||||
T *swapBuffers();
|
||||
};
|
||||
|
||||
template<class T, int size>
|
||||
DoubleBuffer<T,size>::DoubleBuffer()
|
||||
{
|
||||
init ();
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
void DoubleBuffer<T,size>::init()
|
||||
{
|
||||
this->m_dmaPending = false;
|
||||
this->m_frontBuffer = &this->m_buffer0[0];
|
||||
this->m_backBuffer = &this->m_buffer1[0];
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
void
|
||||
DoubleBuffer<T,size>::backBufferDmaGet(uint64_t ea, unsigned int numBytes, unsigned int tag)
|
||||
{
|
||||
m_dmaPending = true;
|
||||
m_dmaTag = tag;
|
||||
if (numBytes)
|
||||
{
|
||||
m_backBuffer = (T*)cellDmaLargeGetReadOnly(m_backBuffer, ea, numBytes, tag, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
void
|
||||
DoubleBuffer<T,size>::backBufferDmaPut(uint64_t ea, unsigned int numBytes, unsigned int tag)
|
||||
{
|
||||
m_dmaPending = true;
|
||||
m_dmaTag = tag;
|
||||
cellDmaLargePut(m_backBuffer, ea, numBytes, tag, 0, 0);
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
T *
|
||||
DoubleBuffer<T,size>::getFront()
|
||||
{
|
||||
return m_frontBuffer;
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
T *
|
||||
DoubleBuffer<T,size>::getBack()
|
||||
{
|
||||
return m_backBuffer;
|
||||
}
|
||||
|
||||
template<class T, int size>
|
||||
T *
|
||||
DoubleBuffer<T,size>::swapBuffers()
|
||||
{
|
||||
if (m_dmaPending)
|
||||
{
|
||||
cellDmaWaitTagStatusAll(1<<m_dmaTag);
|
||||
m_dmaPending = false;
|
||||
}
|
||||
|
||||
T *tmp = m_backBuffer;
|
||||
m_backBuffer = m_frontBuffer;
|
||||
m_frontBuffer = tmp;
|
||||
|
||||
return m_frontBuffer;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/*
|
||||
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 FAKE_DMA_H
|
||||
#define FAKE_DMA_H
|
||||
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
#include "LinearMath/btScalar.h"
|
||||
|
||||
|
||||
#ifdef __SPU__
|
||||
|
||||
#ifndef USE_LIBSPE2
|
||||
|
||||
#include <cell/dma.h>
|
||||
#include <stdint.h>
|
||||
|
||||
#define DMA_TAG(xfer) (xfer + 1)
|
||||
#define DMA_MASK(xfer) (1 << DMA_TAG(xfer))
|
||||
|
||||
#else // !USE_LIBSPE2
|
||||
|
||||
#define DMA_TAG(xfer) (xfer + 1)
|
||||
#define DMA_MASK(xfer) (1 << DMA_TAG(xfer))
|
||||
|
||||
#include <spu_mfcio.h>
|
||||
|
||||
#define DEBUG_DMA
|
||||
#ifdef DEBUG_DMA
|
||||
#define dUASSERT(a,b) if (!(a)) { printf(b);}
|
||||
#define uintsize ppu_address_t
|
||||
|
||||
#define cellDmaLargeGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \
|
||||
dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \
|
||||
dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \
|
||||
dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \
|
||||
dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \
|
||||
dUASSERT(size < 16384, "size too big: "); \
|
||||
dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \
|
||||
dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\
|
||||
printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\
|
||||
} \
|
||||
mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \
|
||||
dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \
|
||||
dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \
|
||||
dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \
|
||||
dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \
|
||||
dUASSERT(size < 16384, "size too big: "); \
|
||||
dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \
|
||||
dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\
|
||||
printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\
|
||||
} \
|
||||
mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaLargePut(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \
|
||||
dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \
|
||||
dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \
|
||||
dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \
|
||||
dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \
|
||||
dUASSERT(size < 16384, "size too big: "); \
|
||||
dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \
|
||||
dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\
|
||||
printf("PUT %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ls,(unsigned int)ea,(unsigned int)size); \
|
||||
} \
|
||||
mfc_put(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaSmallGet(ls, ea, size, tag, tid, rid) if ( (((uintsize)ls%16) != ((uintsize)ea%16)) || ((((uintsize)ea%16) || ((uintsize)ls%16)) && (( ((uintsize)ls%16) != ((uintsize)size%16) ) || ( ((uintsize)ea%16) != ((uintsize)size%16) ) ) ) || ( ((uintsize)size%16) && ((uintsize)size!=1) && ((uintsize)size!=2) && ((uintsize)size!=4) && ((uintsize)size!=8) ) || (size >= 16384) || !(uintsize)ls || !(uintsize)ea) { \
|
||||
dUASSERT( (((uintsize)ea % 16) == 0) || (size < 16), "XDR Address not aligned: "); \
|
||||
dUASSERT( (((uintsize)ls % 16) == 0) || (size < 16), "LS Address not aligned: "); \
|
||||
dUASSERT( ((((uintsize)ls % size) == 0) && (((uintsize)ea % size) == 0)) || (size > 16), "Not naturally aligned: "); \
|
||||
dUASSERT((size == 1) || (size == 2) || (size == 4) || (size == 8) || ((size % 16) == 0), "size not a multiple of 16byte: "); \
|
||||
dUASSERT(size < 16384, "size too big: "); \
|
||||
dUASSERT( ((uintsize)ea%16)==((uintsize)ls%16), "wrong Quadword alignment of LS and EA: "); \
|
||||
dUASSERT(ea != 0, "Nullpointer EA: "); dUASSERT(ls != 0, "Nullpointer LS: ");\
|
||||
printf("GET %s:%d from: 0x%x, to: 0x%x - %d bytes\n", __FILE__, __LINE__, (unsigned int)ea,(unsigned int)ls,(unsigned int)size);\
|
||||
} \
|
||||
mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaWaitTagStatusAll(ignore) mfc_write_tag_mask(ignore) ; mfc_read_tag_status_all()
|
||||
|
||||
#else
|
||||
#define cellDmaLargeGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaLargePut(ls, ea, size, tag, tid, rid) mfc_put(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaSmallGet(ls, ea, size, tag, tid, rid) mfc_get(ls, ea, size, tag, tid, rid)
|
||||
#define cellDmaWaitTagStatusAll(ignore) mfc_write_tag_mask(ignore) ; mfc_read_tag_status_all()
|
||||
#endif // DEBUG_DMA
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
#endif // USE_LIBSPE2
|
||||
#else // !__SPU__
|
||||
//Simulate DMA using memcpy or direct access on non-CELL platforms that don't have DMAs and SPUs (Win32, Mac, Linux etc)
|
||||
//Potential to add networked simulation using this interface
|
||||
|
||||
#define DMA_TAG(a) (a)
|
||||
#define DMA_MASK(a) (a)
|
||||
|
||||
/// cellDmaLargeGet Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy)
|
||||
int cellDmaLargeGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
int cellDmaGet(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
/// cellDmaLargePut Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy)
|
||||
int cellDmaLargePut(const void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
/// cellDmaWaitTagStatusAll Win32 replacements for Cell DMA to allow simulating most of the SPU code (just memcpy)
|
||||
void cellDmaWaitTagStatusAll(int ignore);
|
||||
|
||||
|
||||
#endif //__CELLOS_LV2__
|
||||
|
||||
///stallingUnalignedDmaSmallGet internally uses DMA_TAG(1)
|
||||
int stallingUnalignedDmaSmallGet(void *ls, uint64_t ea, uint32_t size);
|
||||
|
||||
|
||||
void* cellDmaLargeGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
void* cellDmaGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
void* cellDmaSmallGetReadOnly(void *ls, uint64_t ea, uint32_t size, uint32_t tag, uint32_t tid, uint32_t rid);
|
||||
|
||||
|
||||
#endif //FAKE_DMA_H
|
||||
|
|
@ -0,0 +1,72 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
#ifndef SPU_GATHERING_COLLISION__DISPATCHER_H
|
||||
#define SPU_GATHERING_COLLISION__DISPATCHER_H
|
||||
|
||||
#include "BulletCollision/CollisionDispatch/btCollisionDispatcher.h"
|
||||
|
||||
|
||||
///Tuning value to optimized SPU utilization
|
||||
///Too small value means Task overhead is large compared to computation (too fine granularity)
|
||||
///Too big value might render some SPUs are idle, while a few other SPUs are doing all work.
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 8
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 16
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 64
|
||||
#define SPU_BATCHSIZE_BROADPHASE_PAIRS 128
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 256
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 512
|
||||
//#define SPU_BATCHSIZE_BROADPHASE_PAIRS 1024
|
||||
|
||||
|
||||
|
||||
class SpuCollisionTaskProcess;
|
||||
|
||||
///SpuGatheringCollisionDispatcher can use SPU to gather and calculate collision detection
|
||||
///Time of Impact, Closest Points and Penetration Depth.
|
||||
class SpuGatheringCollisionDispatcher : public btCollisionDispatcher
|
||||
{
|
||||
|
||||
SpuCollisionTaskProcess* m_spuCollisionTaskProcess;
|
||||
|
||||
protected:
|
||||
|
||||
class btThreadSupportInterface* m_threadInterface;
|
||||
|
||||
unsigned int m_maxNumOutstandingTasks;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
//can be used by SPU collision algorithms
|
||||
SpuCollisionTaskProcess* getSpuCollisionTaskProcess()
|
||||
{
|
||||
return m_spuCollisionTaskProcess;
|
||||
}
|
||||
|
||||
SpuGatheringCollisionDispatcher (class btThreadSupportInterface* threadInterface, unsigned int maxNumOutstandingTasks,btCollisionConfiguration* collisionConfiguration);
|
||||
|
||||
virtual ~SpuGatheringCollisionDispatcher();
|
||||
|
||||
bool supportsDispatchPairOnSpu(int proxyType0,int proxyType1);
|
||||
|
||||
virtual void dispatchAllCollisionPairs(btOverlappingPairCache* pairCache,const btDispatcherInfo& dispatchInfo,btDispatcher* dispatcher) ;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //SPU_GATHERING_COLLISION__DISPATCHER_H
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
|
||||
#ifndef SPU_LIBSPE2_SUPPORT_H
|
||||
#define SPU_LIBSPE2_SUPPORT_H
|
||||
|
||||
#include <LinearMath/btScalar.h> //for uint32_t etc.
|
||||
|
||||
#ifdef USE_LIBSPE2
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
//#include "SpuNarrowPhaseCollisionTask/SpuGatheringCollisionTask.h"
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
|
||||
//extern struct SpuGatherAndProcessPairsTaskDesc;
|
||||
|
||||
enum
|
||||
{
|
||||
Spu_Mailbox_Event_Nothing = 0,
|
||||
Spu_Mailbox_Event_Task = 1,
|
||||
Spu_Mailbox_Event_Shutdown = 2,
|
||||
|
||||
Spu_Mailbox_Event_ForceDword = 0xFFFFFFFF
|
||||
|
||||
};
|
||||
|
||||
enum
|
||||
{
|
||||
Spu_Status_Free = 0,
|
||||
Spu_Status_Occupied = 1,
|
||||
Spu_Status_Startup = 2,
|
||||
|
||||
Spu_Status_ForceDword = 0xFFFFFFFF
|
||||
|
||||
};
|
||||
|
||||
|
||||
struct btSpuStatus
|
||||
{
|
||||
uint32_t m_taskId;
|
||||
uint32_t m_commandId;
|
||||
uint32_t m_status;
|
||||
|
||||
addr64 m_taskDesc;
|
||||
addr64 m_lsMemory;
|
||||
|
||||
}
|
||||
__attribute__ ((aligned (128)))
|
||||
;
|
||||
|
||||
|
||||
|
||||
#ifndef __SPU__
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
#include "SpuCollisionTaskProcess.h"
|
||||
#include "SpuSampleTaskProcess.h"
|
||||
#include "btThreadSupportInterface.h"
|
||||
#include <libspe2.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
|
||||
#define MAX_SPUS 4
|
||||
|
||||
typedef struct ppu_pthread_data
|
||||
{
|
||||
spe_context_ptr_t context;
|
||||
pthread_t pthread;
|
||||
unsigned int entry;
|
||||
unsigned int flags;
|
||||
addr64 argp;
|
||||
addr64 envp;
|
||||
spe_stop_info_t stopinfo;
|
||||
} ppu_pthread_data_t;
|
||||
|
||||
|
||||
static void *ppu_pthread_function(void *arg)
|
||||
{
|
||||
ppu_pthread_data_t * datap = (ppu_pthread_data_t *)arg;
|
||||
/*
|
||||
int rc;
|
||||
do
|
||||
{*/
|
||||
spe_context_run(datap->context, &datap->entry, datap->flags, datap->argp.p, datap->envp.p, &datap->stopinfo);
|
||||
if (datap->stopinfo.stop_reason == SPE_EXIT)
|
||||
{
|
||||
if (datap->stopinfo.result.spe_exit_code != 0)
|
||||
{
|
||||
perror("FAILED: SPE returned a non-zero exit status: \n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
perror("FAILED: SPE abnormally terminated\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
//} while (rc > 0); // loop until exit or error, and while any stop & signal
|
||||
pthread_exit(NULL);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
///SpuLibspe2Support helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
|
||||
class SpuLibspe2Support : public btThreadSupportInterface
|
||||
{
|
||||
|
||||
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
|
||||
|
||||
public:
|
||||
//Setup and initialize SPU/CELL/Libspe2
|
||||
SpuLibspe2Support(spe_program_handle_t *speprog,int numThreads);
|
||||
|
||||
// SPE program handle ptr.
|
||||
spe_program_handle_t *program;
|
||||
|
||||
// SPE program data
|
||||
ppu_pthread_data_t data[MAX_SPUS];
|
||||
|
||||
//cleanup/shutdown Libspe2
|
||||
~SpuLibspe2Support();
|
||||
|
||||
///send messages to SPUs
|
||||
void sendRequest(uint32_t uiCommand, uint32_t uiArgument0, uint32_t uiArgument1=0);
|
||||
|
||||
//check for messages from SPUs
|
||||
void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
|
||||
|
||||
//start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
virtual void startSPU();
|
||||
|
||||
//tell the task scheduler we are done with the SPU tasks
|
||||
virtual void stopSPU();
|
||||
|
||||
virtual void setNumTasks(int numTasks)
|
||||
{
|
||||
//changing the number of tasks after initialization is not implemented (yet)
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
void internal_startSPU();
|
||||
|
||||
|
||||
|
||||
|
||||
int numThreads;
|
||||
|
||||
};
|
||||
|
||||
#endif // NOT __SPU__
|
||||
|
||||
#endif //USE_LIBSPE2
|
||||
|
||||
#endif //SPU_LIBSPE2_SUPPORT_H
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,167 @@
|
|||
/*
|
||||
Copyright (C) 2006, 2008 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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 __BOX_H__
|
||||
#define __BOX_H__
|
||||
|
||||
|
||||
#ifndef PE_REF
|
||||
#define PE_REF(a) a&
|
||||
#endif
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "../PlatformDefinitions.h"
|
||||
|
||||
|
||||
|
||||
|
||||
enum FeatureType { F, E, V };
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
// Box
|
||||
//----------------------------------------------------------------------------
|
||||
///The Box is an internal class used by the boxBoxDistance calculation.
|
||||
class Box
|
||||
{
|
||||
public:
|
||||
vmVector3 mHalf;
|
||||
|
||||
inline Box()
|
||||
{}
|
||||
inline Box(PE_REF(vmVector3) half_);
|
||||
inline Box(float hx, float hy, float hz);
|
||||
|
||||
inline void Set(PE_REF(vmVector3) half_);
|
||||
inline void Set(float hx, float hy, float hz);
|
||||
|
||||
inline vmVector3 GetAABB(const vmMatrix3& rotation) const;
|
||||
};
|
||||
|
||||
inline
|
||||
Box::Box(PE_REF(vmVector3) half_)
|
||||
{
|
||||
Set(half_);
|
||||
}
|
||||
|
||||
inline
|
||||
Box::Box(float hx, float hy, float hz)
|
||||
{
|
||||
Set(hx, hy, hz);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
Box::Set(PE_REF(vmVector3) half_)
|
||||
{
|
||||
mHalf = half_;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
Box::Set(float hx, float hy, float hz)
|
||||
{
|
||||
mHalf = vmVector3(hx, hy, hz);
|
||||
}
|
||||
|
||||
inline
|
||||
vmVector3
|
||||
Box::GetAABB(const vmMatrix3& rotation) const
|
||||
{
|
||||
return absPerElem(rotation) * mHalf;
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
// BoxPoint
|
||||
//-------------------------------------------------------------------------------------------------
|
||||
|
||||
///The BoxPoint class is an internally used class to contain feature information for boxBoxDistance calculation.
|
||||
class BoxPoint
|
||||
{
|
||||
public:
|
||||
BoxPoint() : localPoint(0.0f) {}
|
||||
|
||||
vmPoint3 localPoint;
|
||||
FeatureType featureType;
|
||||
int featureIdx;
|
||||
|
||||
inline void setVertexFeature(int plusX, int plusY, int plusZ);
|
||||
inline void setEdgeFeature(int dim0, int plus0, int dim1, int plus1);
|
||||
inline void setFaceFeature(int dim, int plus);
|
||||
|
||||
inline void getVertexFeature(int & plusX, int & plusY, int & plusZ) const;
|
||||
inline void getEdgeFeature(int & dim0, int & plus0, int & dim1, int & plus1) const;
|
||||
inline void getFaceFeature(int & dim, int & plus) const;
|
||||
};
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::setVertexFeature(int plusX, int plusY, int plusZ)
|
||||
{
|
||||
featureType = V;
|
||||
featureIdx = plusX << 2 | plusY << 1 | plusZ;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::setEdgeFeature(int dim0, int plus0, int dim1, int plus1)
|
||||
{
|
||||
featureType = E;
|
||||
|
||||
if (dim0 > dim1) {
|
||||
featureIdx = plus1 << 5 | dim1 << 3 | plus0 << 2 | dim0;
|
||||
} else {
|
||||
featureIdx = plus0 << 5 | dim0 << 3 | plus1 << 2 | dim1;
|
||||
}
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::setFaceFeature(int dim, int plus)
|
||||
{
|
||||
featureType = F;
|
||||
featureIdx = plus << 2 | dim;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::getVertexFeature(int & plusX, int & plusY, int & plusZ) const
|
||||
{
|
||||
plusX = featureIdx >> 2;
|
||||
plusY = featureIdx >> 1 & 1;
|
||||
plusZ = featureIdx & 1;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::getEdgeFeature(int & dim0, int & plus0, int & dim1, int & plus1) const
|
||||
{
|
||||
plus0 = featureIdx >> 5;
|
||||
dim0 = featureIdx >> 3 & 3;
|
||||
plus1 = featureIdx >> 2 & 1;
|
||||
dim1 = featureIdx & 3;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
BoxPoint::getFaceFeature(int & dim, int & plus) const
|
||||
{
|
||||
plus = featureIdx >> 2;
|
||||
dim = featureIdx & 3;
|
||||
}
|
||||
|
||||
#endif /* __BOX_H__ */
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/*
|
||||
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 __SPU_COLLISION_SHAPES_H
|
||||
#define __SPU_COLLISION_SHAPES_H
|
||||
|
||||
#include "../SpuDoubleBuffer.h"
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
#include "BulletCollision/CollisionShapes/btConvexInternalShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btCylinderShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btStaticPlaneShape.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btOptimizedBvh.h"
|
||||
#include "BulletCollision/CollisionShapes/btTriangleIndexVertexArray.h"
|
||||
#include "BulletCollision/CollisionShapes/btSphereShape.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btCapsuleShape.h"
|
||||
|
||||
#include "BulletCollision/CollisionShapes/btConvexShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btBvhTriangleMeshShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btConvexHullShape.h"
|
||||
#include "BulletCollision/CollisionShapes/btCompoundShape.h"
|
||||
|
||||
#define MAX_NUM_SPU_CONVEX_POINTS 128 //@fallback to PPU if a btConvexHullShape has more than MAX_NUM_SPU_CONVEX_POINTS points
|
||||
#define MAX_SPU_COMPOUND_SUBSHAPES 16 //@fallback on PPU if compound has more than MAX_SPU_COMPOUND_SUBSHAPES child shapes
|
||||
#define MAX_SHAPE_SIZE 256 //@todo: assert on this
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) SpuConvexPolyhedronVertexData
|
||||
{
|
||||
void* gSpuConvexShapePtr;
|
||||
btVector3* gConvexPoints;
|
||||
int gNumConvexPoints;
|
||||
int unused;
|
||||
ATTRIBUTE_ALIGNED16(btVector3 g_convexPointBuffer[MAX_NUM_SPU_CONVEX_POINTS]);
|
||||
};
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) CollisionShape_LocalStoreMemory
|
||||
{
|
||||
ATTRIBUTE_ALIGNED16(char collisionShape[MAX_SHAPE_SIZE]);
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) CompoundShape_LocalStoreMemory
|
||||
{
|
||||
// Compound data
|
||||
|
||||
ATTRIBUTE_ALIGNED16(btCompoundShapeChild gSubshapes[MAX_SPU_COMPOUND_SUBSHAPES]);
|
||||
ATTRIBUTE_ALIGNED16(char gSubshapeShape[MAX_SPU_COMPOUND_SUBSHAPES][MAX_SHAPE_SIZE]);
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) bvhMeshShape_LocalStoreMemory
|
||||
{
|
||||
//ATTRIBUTE_ALIGNED16(btOptimizedBvh gOptimizedBvh);
|
||||
ATTRIBUTE_ALIGNED16(char gOptimizedBvh[sizeof(btOptimizedBvh)+16]);
|
||||
btOptimizedBvh* getOptimizedBvh()
|
||||
{
|
||||
return (btOptimizedBvh*) gOptimizedBvh;
|
||||
}
|
||||
|
||||
ATTRIBUTE_ALIGNED16(btTriangleIndexVertexArray gTriangleMeshInterfaceStorage);
|
||||
btTriangleIndexVertexArray* gTriangleMeshInterfacePtr;
|
||||
///only a single mesh part for now, we can add support for multiple parts, but quantized trees don't support this at the moment
|
||||
ATTRIBUTE_ALIGNED16(btIndexedMesh gIndexMesh);
|
||||
#define MAX_SPU_SUBTREE_HEADERS 32
|
||||
//1024
|
||||
ATTRIBUTE_ALIGNED16(btBvhSubtreeInfo gSubtreeHeaders[MAX_SPU_SUBTREE_HEADERS]);
|
||||
ATTRIBUTE_ALIGNED16(btQuantizedBvhNode gSubtreeNodes[MAX_SUBTREE_SIZE_IN_BYTES/sizeof(btQuantizedBvhNode)]);
|
||||
};
|
||||
|
||||
|
||||
void computeAabb (btVector3& aabbMin, btVector3& aabbMax, btConvexInternalShape* convexShape, ppu_address_t convexShapePtr, int shapeType, const btTransform& xform);
|
||||
void dmaBvhShapeData (bvhMeshShape_LocalStoreMemory* bvhMeshShape, btBvhTriangleMeshShape* triMeshShape);
|
||||
void dmaBvhIndexedMesh (btIndexedMesh* IndexMesh, IndexedMeshArray& indexArray, int index, uint32_t dmaTag);
|
||||
void dmaBvhSubTreeHeaders (btBvhSubtreeInfo* subTreeHeaders, ppu_address_t subTreePtr, int batchSize, uint32_t dmaTag);
|
||||
void dmaBvhSubTreeNodes (btQuantizedBvhNode* nodes, const btBvhSubtreeInfo& subtree, QuantizedNodeArray& nodeArray, int dmaTag);
|
||||
|
||||
int getShapeTypeSize(int shapeType);
|
||||
void dmaConvexVertexData (SpuConvexPolyhedronVertexData* convexVertexData, btConvexHullShape* convexShapeSPU);
|
||||
void dmaCollisionShape (void* collisionShapeLocation, ppu_address_t collisionShapePtr, uint32_t dmaTag, int shapeType);
|
||||
void dmaCompoundShapeInfo (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag);
|
||||
void dmaCompoundSubShapes (CompoundShape_LocalStoreMemory* compoundShapeLocation, btCompoundShape* spuCompoundShape, uint32_t dmaTag);
|
||||
|
||||
|
||||
#define USE_BRANCHFREE_TEST 1
|
||||
#ifdef USE_BRANCHFREE_TEST
|
||||
SIMD_FORCE_INLINE unsigned int spuTestQuantizedAabbAgainstQuantizedAabb(unsigned short int* aabbMin1,unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
||||
{
|
||||
#if defined(__CELLOS_LV2__) && defined (__SPU__)
|
||||
vec_ushort8 vecMin = {aabbMin1[0],aabbMin2[0],aabbMin1[2],aabbMin2[2],aabbMin1[1],aabbMin2[1],0,0};
|
||||
vec_ushort8 vecMax = {aabbMax2[0],aabbMax1[0],aabbMax2[2],aabbMax1[2],aabbMax2[1],aabbMax1[1],0,0};
|
||||
vec_ushort8 isGt = spu_cmpgt(vecMin,vecMax);
|
||||
return spu_extract(spu_gather(isGt),0)==0;
|
||||
|
||||
#else
|
||||
return btSelect((unsigned)((aabbMin1[0] <= aabbMax2[0]) & (aabbMax1[0] >= aabbMin2[0])
|
||||
& (aabbMin1[2] <= aabbMax2[2]) & (aabbMax1[2] >= aabbMin2[2])
|
||||
& (aabbMin1[1] <= aabbMax2[1]) & (aabbMax1[1] >= aabbMin2[1])),
|
||||
1, 0);
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
|
||||
SIMD_FORCE_INLINE unsigned int spuTestQuantizedAabbAgainstQuantizedAabb(const unsigned short int* aabbMin1,const unsigned short int* aabbMax1,const unsigned short int* aabbMin2,const unsigned short int* aabbMax2)
|
||||
{
|
||||
unsigned int overlap = 1;
|
||||
overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? 0 : overlap;
|
||||
overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? 0 : overlap;
|
||||
overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? 0 : overlap;
|
||||
return overlap;
|
||||
}
|
||||
#endif
|
||||
|
||||
void spuWalkStacklessQuantizedTree(btNodeOverlapCallback* nodeCallback,unsigned short int* quantizedQueryAabbMin,unsigned short int* quantizedQueryAabbMax,const btQuantizedBvhNode* rootNode,int startNodeIndex,int endNodeIndex);
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/*
|
||||
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 SPU_CONTACT_RESULT2_H
|
||||
#define SPU_CONTACT_RESULT2_H
|
||||
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <stdint.h>
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#include "../SpuDoubleBuffer.h"
|
||||
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btPersistentManifold.h"
|
||||
#include "BulletCollision/NarrowPhaseCollision/btDiscreteCollisionDetectorInterface.h"
|
||||
|
||||
class btCollisionShape;
|
||||
|
||||
|
||||
struct SpuCollisionPairInput
|
||||
{
|
||||
ppu_address_t m_collisionShapes[2];
|
||||
btCollisionShape* m_spuCollisionShapes[2];
|
||||
|
||||
ppu_address_t m_persistentManifoldPtr;
|
||||
btVector3 m_primitiveDimensions0;
|
||||
btVector3 m_primitiveDimensions1;
|
||||
int m_shapeType0;
|
||||
int m_shapeType1;
|
||||
float m_collisionMargin0;
|
||||
float m_collisionMargin1;
|
||||
|
||||
btTransform m_worldTransform0;
|
||||
btTransform m_worldTransform1;
|
||||
|
||||
bool m_isSwapped;
|
||||
bool m_useEpa;
|
||||
};
|
||||
|
||||
|
||||
struct SpuClosestPointInput : public btDiscreteCollisionDetectorInterface::ClosestPointInput
|
||||
{
|
||||
struct SpuConvexPolyhedronVertexData* m_convexVertexData[2];
|
||||
};
|
||||
|
||||
///SpuContactResult exports the contact points using double-buffered DMA transfers, only when needed
|
||||
///So when an existing contact point is duplicated, no transfer/refresh is performed.
|
||||
class SpuContactResult : public btDiscreteCollisionDetectorInterface::Result
|
||||
{
|
||||
btTransform m_rootWorldTransform0;
|
||||
btTransform m_rootWorldTransform1;
|
||||
ppu_address_t m_manifoldAddress;
|
||||
|
||||
btPersistentManifold* m_spuManifold;
|
||||
bool m_RequiresWriteBack;
|
||||
btScalar m_combinedFriction;
|
||||
btScalar m_combinedRestitution;
|
||||
|
||||
bool m_isSwapped;
|
||||
|
||||
DoubleBuffer<btPersistentManifold, 1> g_manifoldDmaExport;
|
||||
|
||||
public:
|
||||
SpuContactResult();
|
||||
virtual ~SpuContactResult();
|
||||
|
||||
btPersistentManifold* GetSpuManifold() const
|
||||
{
|
||||
return m_spuManifold;
|
||||
}
|
||||
|
||||
virtual void setShapeIdentifiersA(int partId0,int index0);
|
||||
virtual void setShapeIdentifiersB(int partId1,int index1);
|
||||
|
||||
void setContactInfo(btPersistentManifold* spuManifold, ppu_address_t manifoldAddress,const btTransform& worldTrans0,const btTransform& worldTrans1, btScalar restitution0,btScalar restitution1, btScalar friction0,btScalar friction01, bool isSwapped);
|
||||
|
||||
|
||||
void writeDoubleBufferedManifold(btPersistentManifold* lsManifold, btPersistentManifold* mmManifold);
|
||||
|
||||
virtual void addContactPoint(const btVector3& normalOnBInWorld,const btVector3& pointInWorld,btScalar depth);
|
||||
|
||||
void flush();
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //SPU_CONTACT_RESULT2_H
|
||||
|
||||
|
|
@ -0,0 +1,51 @@
|
|||
|
||||
/*
|
||||
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 SPU_CONVEX_PENETRATION_DEPTH_H
|
||||
#define SPU_CONVEX_PENETRATION_DEPTH_H
|
||||
|
||||
|
||||
|
||||
class btStackAlloc;
|
||||
class btIDebugDraw;
|
||||
#include "BulletCollision/NarrowphaseCollision/btConvexPenetrationDepthSolver.h"
|
||||
|
||||
#include "LinearMath/btTransform.h"
|
||||
|
||||
|
||||
///ConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
|
||||
class SpuConvexPenetrationDepthSolver : public btConvexPenetrationDepthSolver
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~SpuConvexPenetrationDepthSolver() {};
|
||||
virtual bool calcPenDepth( SpuVoronoiSimplexSolver& simplexSolver,
|
||||
void* convexA,void* convexB,int shapeTypeA, int shapeTypeB, float marginA, float marginB,
|
||||
btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc,
|
||||
struct SpuConvexPolyhedronVertexData* convexVertexDataA,
|
||||
struct SpuConvexPolyhedronVertexData* convexVertexDataB
|
||||
) const = 0;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //SPU_CONVEX_PENETRATION_DEPTH_H
|
||||
|
||||
|
|
@ -0,0 +1,140 @@
|
|||
/*
|
||||
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 SPU_GATHERING_COLLISION_TASK_H
|
||||
#define SPU_GATHERING_COLLISION_TASK_H
|
||||
|
||||
#include "../PlatformDefinitions.h"
|
||||
//#define DEBUG_SPU_COLLISION_DETECTION 1
|
||||
|
||||
|
||||
///Task Description for SPU collision detection
|
||||
struct SpuGatherAndProcessPairsTaskDesc
|
||||
{
|
||||
ppu_address_t m_inPairPtr;//m_pairArrayPtr;
|
||||
//mutex variable
|
||||
uint32_t m_someMutexVariableInMainMemory;
|
||||
|
||||
ppu_address_t m_dispatcher;
|
||||
|
||||
uint32_t numOnLastPage;
|
||||
|
||||
uint16_t numPages;
|
||||
uint16_t taskId;
|
||||
bool m_useEpa;
|
||||
|
||||
struct CollisionTask_LocalStoreMemory* m_lsMemory;
|
||||
}
|
||||
|
||||
#if defined(__CELLOS_LV2__) || defined(USE_LIBSPE2)
|
||||
__attribute__ ((aligned (128)))
|
||||
#endif
|
||||
;
|
||||
|
||||
|
||||
void processCollisionTask(void* userPtr, void* lsMemory);
|
||||
|
||||
void* createCollisionLocalStoreMemory();
|
||||
|
||||
|
||||
#if defined(USE_LIBSPE2) && defined(__SPU__)
|
||||
#include "../SpuLibspe2Support.h"
|
||||
#include <spu_intrinsics.h>
|
||||
#include <spu_mfcio.h>
|
||||
#include <SpuFakeDma.h>
|
||||
|
||||
//#define DEBUG_LIBSPE2_SPU_TASK
|
||||
|
||||
|
||||
|
||||
int main(unsigned long long speid, addr64 argp, addr64 envp)
|
||||
{
|
||||
printf("SPU: hello \n");
|
||||
|
||||
ATTRIBUTE_ALIGNED128(btSpuStatus status);
|
||||
ATTRIBUTE_ALIGNED16( SpuGatherAndProcessPairsTaskDesc taskDesc ) ;
|
||||
unsigned int received_message = Spu_Mailbox_Event_Nothing;
|
||||
bool shutdown = false;
|
||||
|
||||
cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
status.m_status = Spu_Status_Free;
|
||||
status.m_lsMemory.p = createCollisionLocalStoreMemory();
|
||||
|
||||
cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
|
||||
while ( btLikely( !shutdown ) )
|
||||
{
|
||||
|
||||
received_message = spu_read_in_mbox();
|
||||
|
||||
if( btLikely( received_message == Spu_Mailbox_Event_Task ))
|
||||
{
|
||||
#ifdef DEBUG_LIBSPE2_SPU_TASK
|
||||
printf("SPU: received Spu_Mailbox_Event_Task\n");
|
||||
#endif //DEBUG_LIBSPE2_SPU_TASK
|
||||
|
||||
// refresh the status
|
||||
cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
btAssert(status.m_status==Spu_Status_Occupied);
|
||||
|
||||
cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuGatherAndProcessPairsTaskDesc), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
#ifdef DEBUG_LIBSPE2_SPU_TASK
|
||||
printf("SPU:processCollisionTask\n");
|
||||
#endif //DEBUG_LIBSPE2_SPU_TASK
|
||||
processCollisionTask((void*)&taskDesc, taskDesc.m_lsMemory);
|
||||
|
||||
#ifdef DEBUG_LIBSPE2_SPU_TASK
|
||||
printf("SPU:finished processCollisionTask\n");
|
||||
#endif //DEBUG_LIBSPE2_SPU_TASK
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG_LIBSPE2_SPU_TASK
|
||||
printf("SPU: received ShutDown\n");
|
||||
#endif //DEBUG_LIBSPE2_SPU_TASK
|
||||
if( btLikely( received_message == Spu_Mailbox_Event_Shutdown ) )
|
||||
{
|
||||
shutdown = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("SPU - Sth. recieved\n");
|
||||
}
|
||||
}
|
||||
|
||||
// set to status free and wait for next task
|
||||
status.m_status = Spu_Status_Free;
|
||||
cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
|
||||
}
|
||||
|
||||
printf("SPU: shutdown\n");
|
||||
return 0;
|
||||
}
|
||||
#endif // USE_LIBSPE2
|
||||
|
||||
|
||||
#endif //SPU_GATHERING_COLLISION_TASK_H
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
/*
|
||||
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 MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
|
||||
#define MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
|
||||
|
||||
|
||||
#include "BulletCollision/NarrowPhaseCollision/btConvexPenetrationDepthSolver.h"
|
||||
|
||||
class btStackAlloc;
|
||||
class btIDebugDraw;
|
||||
class btVoronoiSimplexSolver;
|
||||
class btConvexShape;
|
||||
|
||||
///MinkowskiPenetrationDepthSolver implements bruteforce penetration depth estimation.
|
||||
///Implementation is based on sampling the depth using support mapping, and using GJK step to get the witness points.
|
||||
class SpuMinkowskiPenetrationDepthSolver : public btConvexPenetrationDepthSolver
|
||||
{
|
||||
public:
|
||||
SpuMinkowskiPenetrationDepthSolver() {}
|
||||
virtual ~SpuMinkowskiPenetrationDepthSolver() {};
|
||||
|
||||
virtual bool calcPenDepth( btSimplexSolverInterface& simplexSolver,
|
||||
const btConvexShape* convexA,const btConvexShape* convexB,
|
||||
const btTransform& transA,const btTransform& transB,
|
||||
btVector3& v, btVector3& pa, btVector3& pb,
|
||||
class btIDebugDraw* debugDraw,btStackAlloc* stackAlloc
|
||||
);
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
#endif //MINKOWSKI_PENETRATION_DEPTH_SOLVER_H
|
||||
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 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 _SPU_PREFERRED_PENETRATION_DIRECTIONS_H
|
||||
#define _SPU_PREFERRED_PENETRATION_DIRECTIONS_H
|
||||
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btBroadphaseProxy.h"
|
||||
|
||||
int spuGetNumPreferredPenetrationDirections(int shapeType, void* shape)
|
||||
{
|
||||
switch (shapeType)
|
||||
{
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
return 2;
|
||||
//spu_printf("2\n");
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
#if __ASSERT
|
||||
spu_printf("spuGetNumPreferredPenetrationDirections() - Unsupported bound type: %d.\n", shapeType);
|
||||
#endif // __ASSERT
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void spuGetPreferredPenetrationDirection(int shapeType, void* shape, int index, btVector3& penetrationVector)
|
||||
{
|
||||
|
||||
|
||||
switch (shapeType)
|
||||
{
|
||||
case TRIANGLE_SHAPE_PROXYTYPE:
|
||||
{
|
||||
btVector3* vertices = (btVector3*)shape;
|
||||
///calcNormal
|
||||
penetrationVector = (vertices[1]-vertices[0]).cross(vertices[2]-vertices[0]);
|
||||
penetrationVector.normalize();
|
||||
if (index)
|
||||
penetrationVector *= btScalar(-1.);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
|
||||
#if __ASSERT
|
||||
spu_printf("spuGetNumPreferredPenetrationDirections() - Unsupported bound type: %d.\n", shapeType);
|
||||
#endif // __ASSERT
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif //_SPU_PREFERRED_PENETRATION_DIRECTIONS_H
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
Copyright (C) 2006, 2008 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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 __BOXBOXDISTANCE_H__
|
||||
#define __BOXBOXDISTANCE_H__
|
||||
|
||||
|
||||
#include "Box.h"
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// boxBoxDistance:
|
||||
//
|
||||
// description:
|
||||
// this computes info that can be used for the collision response of two boxes. when the boxes
|
||||
// do not overlap, the points are set to the closest points of the boxes, and a positive
|
||||
// distance between them is returned. if the boxes do overlap, a negative distance is returned
|
||||
// and the points are set to two points that would touch after the boxes are translated apart.
|
||||
// the contact normal gives the direction to repel or separate the boxes when they touch or
|
||||
// overlap (it's being approximated here as one of the 15 "separating axis" directions).
|
||||
//
|
||||
// returns:
|
||||
// positive or negative distance between two boxes.
|
||||
//
|
||||
// args:
|
||||
// vmVector3& normal: set to a unit contact normal pointing from box A to box B.
|
||||
//
|
||||
// BoxPoint& boxPointA, BoxPoint& boxPointB:
|
||||
// set to a closest point or point of penetration on each box.
|
||||
//
|
||||
// Box boxA, Box boxB:
|
||||
// boxes, represented as 3 half-widths
|
||||
//
|
||||
// const vmTransform3& transformA, const vmTransform3& transformB:
|
||||
// box transformations, in world coordinates
|
||||
//
|
||||
// float distanceThreshold:
|
||||
// the algorithm will exit early if it finds that the boxes are more distant than this
|
||||
// threshold, and not compute a contact normal or points. if this distance returned
|
||||
// exceeds the threshold, all the other output data may not have been computed. by
|
||||
// default, this is set to MAX_FLOAT so it will have no effect.
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
float
|
||||
boxBoxDistance(vmVector3& normal, BoxPoint& boxPointA, BoxPoint& boxPointB,
|
||||
PE_REF(Box) boxA, const vmTransform3 & transformA, PE_REF(Box) boxB,
|
||||
const vmTransform3 & transformB,
|
||||
float distanceThreshold = FLT_MAX );
|
||||
|
||||
#endif /* __BOXBOXDISTANCE_H__ */
|
||||
|
|
@ -0,0 +1,54 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, Copyright (c) 2007 Erwin Coumans
|
||||
|
||||
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 SPU_SAMPLE_TASK_H
|
||||
#define SPU_SAMPLE_TASK_H
|
||||
|
||||
#include "../PlatformDefinitions.h"
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
|
||||
#include "LinearMath/btAlignedAllocator.h"
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
CMD_SAMPLE_INTEGRATE_BODIES = 1,
|
||||
CMD_SAMPLE_PREDICT_MOTION_BODIES
|
||||
};
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) SpuSampleTaskDesc
|
||||
{
|
||||
BT_DECLARE_ALIGNED_ALLOCATOR();
|
||||
|
||||
uint32_t m_sampleCommand;
|
||||
uint32_t m_taskId;
|
||||
|
||||
uint64_t m_mainMemoryPtr;
|
||||
int m_sampleValue;
|
||||
|
||||
|
||||
};
|
||||
|
||||
|
||||
void processSampleTask(void* userPtr, void* lsMemory);
|
||||
void* createSampleLocalStoreMemory();
|
||||
|
||||
|
||||
#endif //SPU_SAMPLE_TASK_H
|
||||
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef SPU_SAMPLE_TASK_PROCESS_H
|
||||
#define SPU_SAMPLE_TASK_PROCESS_H
|
||||
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
|
||||
#include "SpuSampleTask/SpuSampleTask.h"
|
||||
|
||||
|
||||
//just add your commands here, try to keep them globally unique for debugging purposes
|
||||
#define CMD_SAMPLE_TASK_COMMAND 10
|
||||
|
||||
|
||||
|
||||
/// SpuSampleTaskProcess handles SPU processing of collision pairs.
|
||||
/// When PPU issues a task, it will look for completed task buffers
|
||||
/// PPU will do postprocessing, dependent on workunit output (not likely)
|
||||
class SpuSampleTaskProcess
|
||||
{
|
||||
// track task buffers that are being used, and total busy tasks
|
||||
btAlignedObjectArray<bool> m_taskBusy;
|
||||
btAlignedObjectArray<SpuSampleTaskDesc>m_spuSampleTaskDesc;
|
||||
|
||||
int m_numBusyTasks;
|
||||
|
||||
// the current task and the current entry to insert a new work unit
|
||||
int m_currentTask;
|
||||
|
||||
bool m_initialized;
|
||||
|
||||
void postProcess(int taskId, int outputSize);
|
||||
|
||||
class btThreadSupportInterface* m_threadInterface;
|
||||
|
||||
int m_maxNumOutstandingTasks;
|
||||
|
||||
|
||||
|
||||
public:
|
||||
SpuSampleTaskProcess(btThreadSupportInterface* threadInterface, int maxNumOutstandingTasks);
|
||||
|
||||
~SpuSampleTaskProcess();
|
||||
|
||||
///call initialize in the beginning of the frame, before addCollisionPairToTask
|
||||
void initialize();
|
||||
|
||||
void issueTask(void* sampleMainMemPtr,int sampleValue,int sampleCommand);
|
||||
|
||||
///call flush to submit potential outstanding work to SPUs and wait for all involved SPUs to be finished
|
||||
void flush();
|
||||
};
|
||||
|
||||
|
||||
#if defined(USE_LIBSPE2) && defined(__SPU__)
|
||||
////////////////////MAIN/////////////////////////////
|
||||
#include "../SpuLibspe2Support.h"
|
||||
#include <spu_intrinsics.h>
|
||||
#include <spu_mfcio.h>
|
||||
#include <SpuFakeDma.h>
|
||||
|
||||
void * SamplelsMemoryFunc();
|
||||
void SampleThreadFunc(void* userPtr,void* lsMemory);
|
||||
|
||||
//#define DEBUG_LIBSPE2_MAINLOOP
|
||||
|
||||
int main(unsigned long long speid, addr64 argp, addr64 envp)
|
||||
{
|
||||
printf("SPU is up \n");
|
||||
|
||||
ATTRIBUTE_ALIGNED128(btSpuStatus status);
|
||||
ATTRIBUTE_ALIGNED16( SpuSampleTaskDesc taskDesc ) ;
|
||||
unsigned int received_message = Spu_Mailbox_Event_Nothing;
|
||||
bool shutdown = false;
|
||||
|
||||
cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
status.m_status = Spu_Status_Free;
|
||||
status.m_lsMemory.p = SamplelsMemoryFunc();
|
||||
|
||||
cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
|
||||
while (!shutdown)
|
||||
{
|
||||
received_message = spu_read_in_mbox();
|
||||
|
||||
|
||||
|
||||
switch(received_message)
|
||||
{
|
||||
case Spu_Mailbox_Event_Shutdown:
|
||||
shutdown = true;
|
||||
break;
|
||||
case Spu_Mailbox_Event_Task:
|
||||
// refresh the status
|
||||
#ifdef DEBUG_LIBSPE2_MAINLOOP
|
||||
printf("SPU recieved Task \n");
|
||||
#endif //DEBUG_LIBSPE2_MAINLOOP
|
||||
cellDmaGet(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
btAssert(status.m_status==Spu_Status_Occupied);
|
||||
|
||||
cellDmaGet(&taskDesc, status.m_taskDesc.p, sizeof(SpuSampleTaskDesc), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
SampleThreadFunc((void*)&taskDesc, reinterpret_cast<void*> (taskDesc.m_mainMemoryPtr) );
|
||||
break;
|
||||
case Spu_Mailbox_Event_Nothing:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// set to status free and wait for next task
|
||||
status.m_status = Spu_Status_Free;
|
||||
cellDmaLargePut(&status, argp.ull, sizeof(btSpuStatus), DMA_TAG(3), 0, 0);
|
||||
cellDmaWaitTagStatusAll(DMA_MASK(3));
|
||||
|
||||
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
//////////////////////////////////////////////////////
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
#endif // SPU_SAMPLE_TASK_PROCESS_H
|
||||
|
||||
148
Mod Sources/Bullet/include/bullet/BulletMultiThreaded/SpuSync.h
Normal file
148
Mod Sources/Bullet/include/bullet/BulletMultiThreaded/SpuSync.h
Normal file
|
|
@ -0,0 +1,148 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2007 Starbreeze Studios
|
||||
|
||||
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.
|
||||
|
||||
Written by: Marten Svanfeldt
|
||||
*/
|
||||
|
||||
#ifndef SPU_SYNC_H
|
||||
#define SPU_SYNC_H
|
||||
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
|
||||
#if defined(WIN32)
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#ifdef _XBOX
|
||||
#include <Xtl.h>
|
||||
#else
|
||||
#include <Windows.h>
|
||||
#endif
|
||||
|
||||
///The btSpinlock is a structure to allow multi-platform synchronization. This allows to port the SPU tasks to other platforms.
|
||||
class btSpinlock
|
||||
{
|
||||
public:
|
||||
//typedef volatile LONG SpinVariable;
|
||||
typedef CRITICAL_SECTION SpinVariable;
|
||||
|
||||
btSpinlock (SpinVariable* var)
|
||||
: spinVariable (var)
|
||||
{}
|
||||
|
||||
void Init ()
|
||||
{
|
||||
//*spinVariable = 0;
|
||||
InitializeCriticalSection(spinVariable);
|
||||
}
|
||||
|
||||
void Lock ()
|
||||
{
|
||||
EnterCriticalSection(spinVariable);
|
||||
}
|
||||
|
||||
void Unlock ()
|
||||
{
|
||||
LeaveCriticalSection(spinVariable);
|
||||
}
|
||||
|
||||
private:
|
||||
SpinVariable* spinVariable;
|
||||
};
|
||||
|
||||
|
||||
#elif defined (__CELLOS_LV2__)
|
||||
|
||||
//#include <cell/atomic.h>
|
||||
#include <cell/sync/mutex.h>
|
||||
|
||||
///The btSpinlock is a structure to allow multi-platform synchronization. This allows to port the SPU tasks to other platforms.
|
||||
class btSpinlock
|
||||
{
|
||||
public:
|
||||
typedef CellSyncMutex SpinVariable;
|
||||
|
||||
btSpinlock (SpinVariable* var)
|
||||
: spinVariable (var)
|
||||
{}
|
||||
|
||||
void Init ()
|
||||
{
|
||||
#ifndef __SPU__
|
||||
//*spinVariable = 1;
|
||||
cellSyncMutexInitialize(spinVariable);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Lock ()
|
||||
{
|
||||
#ifdef __SPU__
|
||||
// lock semaphore
|
||||
/*while (cellAtomicTestAndDecr32(atomic_buf, (uint64_t)spinVariable) == 0)
|
||||
{
|
||||
|
||||
};*/
|
||||
cellSyncMutexLock((uint64_t)spinVariable);
|
||||
#endif
|
||||
}
|
||||
|
||||
void Unlock ()
|
||||
{
|
||||
#ifdef __SPU__
|
||||
//cellAtomicIncr32(atomic_buf, (uint64_t)spinVariable);
|
||||
cellSyncMutexUnlock((uint64_t)spinVariable);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
SpinVariable* spinVariable;
|
||||
ATTRIBUTE_ALIGNED128(uint32_t atomic_buf[32]);
|
||||
};
|
||||
|
||||
#else
|
||||
//create a dummy implementation (without any locking) useful for serial processing
|
||||
class btSpinlock
|
||||
{
|
||||
public:
|
||||
typedef int SpinVariable;
|
||||
|
||||
btSpinlock (SpinVariable* var)
|
||||
: spinVariable (var)
|
||||
{}
|
||||
|
||||
void Init ()
|
||||
{
|
||||
}
|
||||
|
||||
void Lock ()
|
||||
{
|
||||
}
|
||||
|
||||
void Unlock ()
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
SpinVariable* spinVariable;
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
Copyright (C) 2009 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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 __T_RB_DYN_BODY_H__
|
||||
#define __T_RB_DYN_BODY_H__
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
using namespace Vectormath::Aos;
|
||||
|
||||
#include "TrbStateVec.h"
|
||||
|
||||
class CollObject;
|
||||
|
||||
class TrbDynBody
|
||||
{
|
||||
public:
|
||||
TrbDynBody()
|
||||
{
|
||||
fMass = 0.0f;
|
||||
fCollObject = NULL;
|
||||
fElasticity = 0.2f;
|
||||
fFriction = 0.8f;
|
||||
}
|
||||
|
||||
// Get methods
|
||||
float getMass() const {return fMass;};
|
||||
float getElasticity() const {return fElasticity;}
|
||||
float getFriction() const {return fFriction;}
|
||||
CollObject* getCollObject() const {return fCollObject;}
|
||||
const Matrix3 &getBodyInertia() const {return fIBody;}
|
||||
const Matrix3 &getBodyInertiaInv() const {return fIBodyInv;}
|
||||
float getMassInv() const {return fMassInv;}
|
||||
|
||||
// Set methods
|
||||
void setMass(float mass) {fMass=mass;fMassInv=mass>0.0f?1.0f/mass:0.0f;}
|
||||
void setBodyInertia(const Matrix3 bodyInertia) {fIBody = bodyInertia;fIBodyInv = inverse(bodyInertia);}
|
||||
void setElasticity(float elasticity) {fElasticity = elasticity;}
|
||||
void setFriction(float friction) {fFriction = friction;}
|
||||
void setCollObject(CollObject *collObj) {fCollObject = collObj;}
|
||||
|
||||
void setBodyInertiaInv(const Matrix3 bodyInertiaInv)
|
||||
{
|
||||
fIBody = inverse(bodyInertiaInv);
|
||||
fIBodyInv = bodyInertiaInv;
|
||||
}
|
||||
void setMassInv(float invMass) {
|
||||
fMass= invMass>0.0f ? 1.0f/invMass :0.0f;
|
||||
fMassInv=invMass;
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
// Rigid Body constants
|
||||
float fMass; // Rigid Body mass
|
||||
float fMassInv; // Inverse of mass
|
||||
Matrix3 fIBody; // Inertia matrix in body's coords
|
||||
Matrix3 fIBodyInv; // Inertia matrix inverse in body's coords
|
||||
float fElasticity; // Coefficient of restitution
|
||||
float fFriction; // Coefficient of friction
|
||||
|
||||
public:
|
||||
CollObject* fCollObject; // Collision object corresponding the RB
|
||||
} __attribute__ ((aligned(16)));
|
||||
|
||||
#endif /* __T_RB_DYN_BODY_H__ */
|
||||
|
|
@ -0,0 +1,334 @@
|
|||
/*
|
||||
Copyright (C) 2009 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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 __TRBSTATEVEC_H__
|
||||
#define __TRBSTATEVEC_H__
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "vectormath/vmInclude.h"
|
||||
|
||||
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
|
||||
static inline vmVector3 read_Vector3(const float* p)
|
||||
{
|
||||
vmVector3 v;
|
||||
loadXYZ(v, p);
|
||||
return v;
|
||||
}
|
||||
|
||||
static inline vmQuat read_Quat(const float* p)
|
||||
{
|
||||
vmQuat vq;
|
||||
loadXYZW(vq, p);
|
||||
return vq;
|
||||
}
|
||||
|
||||
static inline void store_Vector3(const vmVector3 &src, float* p)
|
||||
{
|
||||
vmVector3 v = src;
|
||||
storeXYZ(v, p);
|
||||
}
|
||||
|
||||
static inline void store_Quat(const vmQuat &src, float* p)
|
||||
{
|
||||
vmQuat vq = src;
|
||||
storeXYZW(vq, p);
|
||||
}
|
||||
|
||||
// Motion Type
|
||||
enum {
|
||||
PfxMotionTypeFixed = 0,
|
||||
PfxMotionTypeActive,
|
||||
PfxMotionTypeKeyframe,
|
||||
PfxMotionTypeOneWay,
|
||||
PfxMotionTypeTrigger,
|
||||
PfxMotionTypeCount
|
||||
};
|
||||
|
||||
#define PFX_MOTION_MASK_DYNAMIC 0x0a // Active,OneWay
|
||||
#define PFX_MOTION_MASK_STATIC 0x95 // Fixed,Keyframe,Trigger,Sleeping
|
||||
#define PFX_MOTION_MASK_SLEEP 0x0e // Can sleep
|
||||
#define PFX_MOTION_MASK_TYPE 0x7f
|
||||
|
||||
//
|
||||
// Rigid Body state
|
||||
//
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
ATTRIBUTE_ALIGNED128(class) TrbState
|
||||
#else
|
||||
ATTRIBUTE_ALIGNED16(class) TrbState
|
||||
#endif
|
||||
|
||||
{
|
||||
public:
|
||||
TrbState()
|
||||
{
|
||||
setMotionType(PfxMotionTypeActive);
|
||||
contactFilterSelf=contactFilterTarget=0xffffffff;
|
||||
deleted = 0;
|
||||
mSleeping = 0;
|
||||
useSleep = 1;
|
||||
trbBodyIdx=0;
|
||||
mSleepCount=0;
|
||||
useCcd = 0;
|
||||
useContactCallback = 0;
|
||||
useSleepCallback = 0;
|
||||
linearDamping = 1.0f;
|
||||
angularDamping = 0.99f;
|
||||
}
|
||||
|
||||
TrbState(const uint8_t m, const vmVector3& x, const vmQuat& q, const vmVector3& v, const vmVector3& omega );
|
||||
|
||||
uint16_t mSleepCount;
|
||||
uint8_t mMotionType;
|
||||
uint8_t deleted : 1;
|
||||
uint8_t mSleeping : 1;
|
||||
uint8_t useSleep : 1;
|
||||
uint8_t useCcd : 1;
|
||||
uint8_t useContactCallback : 1;
|
||||
uint8_t useSleepCallback : 1;
|
||||
|
||||
uint16_t trbBodyIdx;
|
||||
uint32_t contactFilterSelf;
|
||||
uint32_t contactFilterTarget;
|
||||
|
||||
float center[3]; // AABB center(World)
|
||||
float half[3]; // AABB half(World)
|
||||
|
||||
float linearDamping;
|
||||
float angularDamping;
|
||||
|
||||
float deltaLinearVelocity[3];
|
||||
float deltaAngularVelocity[3];
|
||||
|
||||
float fX[3]; // position
|
||||
float fQ[4]; // orientation
|
||||
float fV[3]; // velocity
|
||||
float fOmega[3]; // angular velocity
|
||||
|
||||
inline void setZero(); // Zeroes out the elements
|
||||
inline void setIdentity(); // Sets the rotation to identity and zeroes out the other elements
|
||||
|
||||
bool isDeleted() const {return deleted==1;}
|
||||
|
||||
uint16_t getRigidBodyId() const {return trbBodyIdx;}
|
||||
void setRigidBodyId(uint16_t i) {trbBodyIdx = i;}
|
||||
|
||||
|
||||
uint32_t getContactFilterSelf() const {return contactFilterSelf;}
|
||||
void setContactFilterSelf(uint32_t filter) {contactFilterSelf = filter;}
|
||||
|
||||
uint32_t getContactFilterTarget() const {return contactFilterTarget;}
|
||||
void setContactFilterTarget(uint32_t filter) {contactFilterTarget = filter;}
|
||||
|
||||
float getLinearDamping() const {return linearDamping;}
|
||||
float getAngularDamping() const {return angularDamping;}
|
||||
|
||||
void setLinearDamping(float damping) {linearDamping=damping;}
|
||||
void setAngularDamping(float damping) {angularDamping=damping;}
|
||||
|
||||
|
||||
uint8_t getMotionType() const {return mMotionType;}
|
||||
void setMotionType(uint8_t t) {mMotionType = t;mSleeping=0;mSleepCount=0;}
|
||||
|
||||
uint8_t getMotionMask() const {return (1<<mMotionType)|(mSleeping<<7);}
|
||||
|
||||
bool isAsleep() const {return mSleeping==1;}
|
||||
bool isAwake() const {return mSleeping==0;}
|
||||
|
||||
void wakeup() {mSleeping=0;mSleepCount=0;}
|
||||
void sleep() {if(useSleep) {mSleeping=1;mSleepCount=0;}}
|
||||
|
||||
uint8_t getUseSleep() const {return useSleep;}
|
||||
void setUseSleep(uint8_t b) {useSleep=b;}
|
||||
|
||||
uint8_t getUseCcd() const {return useCcd;}
|
||||
void setUseCcd(uint8_t b) {useCcd=b;}
|
||||
|
||||
uint8_t getUseContactCallback() const {return useContactCallback;}
|
||||
void setUseContactCallback(uint8_t b) {useContactCallback=b;}
|
||||
|
||||
uint8_t getUseSleepCallback() const {return useSleepCallback;}
|
||||
void setUseSleepCallback(uint8_t b) {useSleepCallback=b;}
|
||||
|
||||
void incrementSleepCount() {mSleepCount++;}
|
||||
void resetSleepCount() {mSleepCount=0;}
|
||||
uint16_t getSleepCount() const {return mSleepCount;}
|
||||
|
||||
vmVector3 getPosition() const {return read_Vector3(fX);}
|
||||
vmQuat getOrientation() const {return read_Quat(fQ);}
|
||||
vmVector3 getLinearVelocity() const {return read_Vector3(fV);}
|
||||
vmVector3 getAngularVelocity() const {return read_Vector3(fOmega);}
|
||||
vmVector3 getDeltaLinearVelocity() const {return read_Vector3(deltaLinearVelocity);}
|
||||
vmVector3 getDeltaAngularVelocity() const {return read_Vector3(deltaAngularVelocity);}
|
||||
|
||||
void setPosition(const vmVector3 &pos) {store_Vector3(pos, fX);}
|
||||
void setLinearVelocity(const vmVector3 &vel) {store_Vector3(vel, fV);}
|
||||
void setAngularVelocity(const vmVector3 &vel) {store_Vector3(vel, fOmega);}
|
||||
void setDeltaLinearVelocity(const vmVector3 &vel) {store_Vector3(vel, deltaLinearVelocity);}
|
||||
void setDeltaAngularVelocity(const vmVector3 &vel) {store_Vector3(vel, deltaAngularVelocity);}
|
||||
void setOrientation(const vmQuat &rot) {store_Quat(rot, fQ);}
|
||||
|
||||
inline void setAuxils(const vmVector3 ¢erLocal,const vmVector3 &halfLocal);
|
||||
inline void setAuxilsCcd(const vmVector3 ¢erLocal,const vmVector3 &halfLocal,float timeStep);
|
||||
inline void reset();
|
||||
};
|
||||
|
||||
inline
|
||||
TrbState::TrbState(const uint8_t m, const vmVector3& x, const vmQuat& q, const vmVector3& v, const vmVector3& omega)
|
||||
{
|
||||
setMotionType(m);
|
||||
fX[0] = x[0];
|
||||
fX[1] = x[1];
|
||||
fX[2] = x[2];
|
||||
fQ[0] = q[0];
|
||||
fQ[1] = q[1];
|
||||
fQ[2] = q[2];
|
||||
fQ[3] = q[3];
|
||||
fV[0] = v[0];
|
||||
fV[1] = v[1];
|
||||
fV[2] = v[2];
|
||||
fOmega[0] = omega[0];
|
||||
fOmega[1] = omega[1];
|
||||
fOmega[2] = omega[2];
|
||||
contactFilterSelf=contactFilterTarget=0xffff;
|
||||
trbBodyIdx=0;
|
||||
mSleeping = 0;
|
||||
deleted = 0;
|
||||
useSleep = 1;
|
||||
useCcd = 0;
|
||||
useContactCallback = 0;
|
||||
useSleepCallback = 0;
|
||||
mSleepCount=0;
|
||||
linearDamping = 1.0f;
|
||||
angularDamping = 0.99f;
|
||||
}
|
||||
|
||||
inline void
|
||||
TrbState::setIdentity()
|
||||
{
|
||||
fX[0] = 0.0f;
|
||||
fX[1] = 0.0f;
|
||||
fX[2] = 0.0f;
|
||||
fQ[0] = 0.0f;
|
||||
fQ[1] = 0.0f;
|
||||
fQ[2] = 0.0f;
|
||||
fQ[3] = 1.0f;
|
||||
fV[0] = 0.0f;
|
||||
fV[1] = 0.0f;
|
||||
fV[2] = 0.0f;
|
||||
fOmega[0] = 0.0f;
|
||||
fOmega[1] = 0.0f;
|
||||
fOmega[2] = 0.0f;
|
||||
}
|
||||
|
||||
inline void
|
||||
TrbState::setZero()
|
||||
{
|
||||
fX[0] = 0.0f;
|
||||
fX[1] = 0.0f;
|
||||
fX[2] = 0.0f;
|
||||
fQ[0] = 0.0f;
|
||||
fQ[1] = 0.0f;
|
||||
fQ[2] = 0.0f;
|
||||
fQ[3] = 0.0f;
|
||||
fV[0] = 0.0f;
|
||||
fV[1] = 0.0f;
|
||||
fV[2] = 0.0f;
|
||||
fOmega[0] = 0.0f;
|
||||
fOmega[1] = 0.0f;
|
||||
fOmega[2] = 0.0f;
|
||||
}
|
||||
|
||||
inline void
|
||||
TrbState::setAuxils(const vmVector3 ¢erLocal,const vmVector3 &halfLocal)
|
||||
{
|
||||
vmVector3 centerW = getPosition() + rotate(getOrientation(),centerLocal);
|
||||
vmVector3 halfW = absPerElem(vmMatrix3(getOrientation())) * halfLocal;
|
||||
center[0] = centerW[0];
|
||||
center[1] = centerW[1];
|
||||
center[2] = centerW[2];
|
||||
half[0] = halfW[0];
|
||||
half[1] = halfW[1];
|
||||
half[2] = halfW[2];
|
||||
}
|
||||
|
||||
inline void
|
||||
TrbState::setAuxilsCcd(const vmVector3 ¢erLocal,const vmVector3 &halfLocal,float timeStep)
|
||||
{
|
||||
vmVector3 centerW = getPosition() + rotate(getOrientation(),centerLocal);
|
||||
vmVector3 halfW = absPerElem(vmMatrix3(getOrientation())) * halfLocal;
|
||||
|
||||
vmVector3 diffvec = getLinearVelocity()*timeStep;
|
||||
|
||||
vmVector3 newCenter = centerW + diffvec;
|
||||
vmVector3 aabbMin = minPerElem(newCenter - halfW,centerW - halfW);
|
||||
vmVector3 aabbMax = maxPerElem(newCenter + halfW,centerW + halfW);
|
||||
|
||||
centerW = 0.5f * (aabbMin + aabbMax);
|
||||
halfW =0.5f * (aabbMax - aabbMin);
|
||||
|
||||
center[0] = centerW[0];
|
||||
center[1] = centerW[1];
|
||||
center[2] = centerW[2];
|
||||
|
||||
half[0] = halfW[0];
|
||||
half[1] = halfW[1];
|
||||
half[2] = halfW[2];
|
||||
}
|
||||
|
||||
inline
|
||||
void TrbState::reset()
|
||||
{
|
||||
#if 0
|
||||
mSleepCount = 0;
|
||||
mMotionType = PfxMotionTypeActive;
|
||||
mDeleted = 0;
|
||||
mSleeping = 0;
|
||||
mUseSleep = 1;
|
||||
mUseCcd = 0;
|
||||
mUseContactCallback = 0;
|
||||
mUseSleepCallback = 0;
|
||||
mRigidBodyId = 0;
|
||||
mContactFilterSelf = 0xffffffff;
|
||||
mContactFilterTarget = 0xffffffff;
|
||||
mLinearDamping = 1.0f;
|
||||
mAngularDamping = 0.99f;
|
||||
mPosition = vmVector3(0.0f);
|
||||
mOrientation = vmQuat::identity();
|
||||
mLinearVelocity = vmVector3(0.0f);
|
||||
mAngularVelocity = vmVector3(0.0f);
|
||||
#endif
|
||||
|
||||
setMotionType(PfxMotionTypeActive);
|
||||
contactFilterSelf=contactFilterTarget=0xffffffff;
|
||||
deleted = 0;
|
||||
mSleeping = 0;
|
||||
useSleep = 1;
|
||||
trbBodyIdx=0;
|
||||
mSleepCount=0;
|
||||
useCcd = 0;
|
||||
useContactCallback = 0;
|
||||
useSleepCallback = 0;
|
||||
linearDamping = 1.0f;
|
||||
angularDamping = 0.99f;
|
||||
}
|
||||
|
||||
#endif /* __TRBSTATEVEC_H__ */
|
||||
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
#ifdef USE_WIN32_THREADING //platform specific defines are defined in PlatformDefinitions.h
|
||||
|
||||
#ifndef WIN32_THREAD_SUPPORT_H
|
||||
#define WIN32_THREAD_SUPPORT_H
|
||||
|
||||
#include "LinearMath/btAlignedObjectArray.h"
|
||||
|
||||
#include "btThreadSupportInterface.h"
|
||||
|
||||
|
||||
typedef void (*Win32ThreadFunc)(void* userPtr,void* lsMemory);
|
||||
typedef void* (*Win32lsMemorySetupFunc)();
|
||||
|
||||
|
||||
///Win32ThreadSupport helps to initialize/shutdown libspe2, start/stop SPU tasks and communication
|
||||
class Win32ThreadSupport : public btThreadSupportInterface
|
||||
{
|
||||
public:
|
||||
///placeholder, until libspe2 support is there
|
||||
struct btSpuStatus
|
||||
{
|
||||
uint32_t m_taskId;
|
||||
uint32_t m_commandId;
|
||||
uint32_t m_status;
|
||||
|
||||
Win32ThreadFunc m_userThreadFunc;
|
||||
void* m_userPtr; //for taskDesc etc
|
||||
void* m_lsMemory; //initialized using Win32LocalStoreMemorySetupFunc
|
||||
|
||||
void* m_threadHandle; //this one is calling 'Win32ThreadFunc'
|
||||
|
||||
void* m_eventStartHandle;
|
||||
char m_eventStartHandleName[32];
|
||||
|
||||
void* m_eventCompletetHandle;
|
||||
char m_eventCompletetHandleName[32];
|
||||
|
||||
|
||||
};
|
||||
private:
|
||||
|
||||
btAlignedObjectArray<btSpuStatus> m_activeSpuStatus;
|
||||
btAlignedObjectArray<void*> m_completeHandles;
|
||||
|
||||
int m_maxNumTasks;
|
||||
public:
|
||||
///Setup and initialize SPU/CELL/Libspe2
|
||||
|
||||
struct Win32ThreadConstructionInfo
|
||||
{
|
||||
Win32ThreadConstructionInfo(char* uniqueName,
|
||||
Win32ThreadFunc userThreadFunc,
|
||||
Win32lsMemorySetupFunc lsMemoryFunc,
|
||||
int numThreads=1,
|
||||
int threadStackSize=65535
|
||||
)
|
||||
:m_uniqueName(uniqueName),
|
||||
m_userThreadFunc(userThreadFunc),
|
||||
m_lsMemoryFunc(lsMemoryFunc),
|
||||
m_numThreads(numThreads),
|
||||
m_threadStackSize(threadStackSize)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
char* m_uniqueName;
|
||||
Win32ThreadFunc m_userThreadFunc;
|
||||
Win32lsMemorySetupFunc m_lsMemoryFunc;
|
||||
int m_numThreads;
|
||||
int m_threadStackSize;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
Win32ThreadSupport(const Win32ThreadConstructionInfo& threadConstructionInfo);
|
||||
|
||||
///cleanup/shutdown Libspe2
|
||||
virtual ~Win32ThreadSupport();
|
||||
|
||||
void startThreads(const Win32ThreadConstructionInfo& threadInfo);
|
||||
|
||||
|
||||
///send messages to SPUs
|
||||
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1);
|
||||
|
||||
///check for messages from SPUs
|
||||
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1);
|
||||
|
||||
virtual bool isTaskCompleted(unsigned int *puiArgument0, unsigned int *puiArgument1, int timeOutInMilliseconds);
|
||||
|
||||
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
virtual void startSPU();
|
||||
|
||||
///tell the task scheduler we are done with the SPU tasks
|
||||
virtual void stopSPU();
|
||||
|
||||
virtual void setNumTasks(int numTasks)
|
||||
{
|
||||
m_maxNumTasks = numTasks;
|
||||
}
|
||||
|
||||
virtual int getNumTasks() const
|
||||
{
|
||||
return m_maxNumTasks;
|
||||
}
|
||||
|
||||
virtual void* getThreadLocalMemory(int taskId)
|
||||
{
|
||||
return m_activeSpuStatus[taskId].m_lsMemory;
|
||||
}
|
||||
virtual btBarrier* createBarrier();
|
||||
|
||||
virtual btCriticalSection* createCriticalSection();
|
||||
|
||||
};
|
||||
|
||||
#endif //WIN32_THREAD_SUPPORT_H
|
||||
|
||||
#endif //USE_WIN32_THREADING
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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 BTGPU3DGRIDBROADPHASE_H
|
||||
#define BTGPU3DGRIDBROADPHASE_H
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "BulletCollision/BroadphaseCollision/btSimpleBroadphase.h"
|
||||
|
||||
#include "btGpu3DGridBroadphaseSharedTypes.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
///The btGpu3DGridBroadphase uses GPU-style code compiled for CPU to compute overlapping pairs
|
||||
|
||||
class btGpu3DGridBroadphase : public btSimpleBroadphase
|
||||
{
|
||||
protected:
|
||||
bool m_bInitialized;
|
||||
unsigned int m_numBodies;
|
||||
unsigned int m_numCells;
|
||||
unsigned int m_maxPairsPerBody;
|
||||
btScalar m_cellFactorAABB;
|
||||
unsigned int m_maxBodiesPerCell;
|
||||
bt3DGridBroadphaseParams m_params;
|
||||
btScalar m_maxRadius;
|
||||
// CPU data
|
||||
unsigned int* m_hBodiesHash;
|
||||
unsigned int* m_hCellStart;
|
||||
unsigned int* m_hPairBuffStartCurr;
|
||||
bt3DGrid3F1U* m_hAABB;
|
||||
unsigned int* m_hPairBuff;
|
||||
unsigned int* m_hPairScan;
|
||||
unsigned int* m_hPairOut;
|
||||
// large proxies
|
||||
int m_numLargeHandles;
|
||||
int m_maxLargeHandles;
|
||||
int m_LastLargeHandleIndex;
|
||||
btSimpleBroadphaseProxy* m_pLargeHandles;
|
||||
void* m_pLargeHandlesRawPtr;
|
||||
int m_firstFreeLargeHandle;
|
||||
int allocLargeHandle()
|
||||
{
|
||||
btAssert(m_numLargeHandles < m_maxLargeHandles);
|
||||
int freeLargeHandle = m_firstFreeLargeHandle;
|
||||
m_firstFreeLargeHandle = m_pLargeHandles[freeLargeHandle].GetNextFree();
|
||||
m_numLargeHandles++;
|
||||
if(freeLargeHandle > m_LastLargeHandleIndex)
|
||||
{
|
||||
m_LastLargeHandleIndex = freeLargeHandle;
|
||||
}
|
||||
return freeLargeHandle;
|
||||
}
|
||||
void freeLargeHandle(btSimpleBroadphaseProxy* proxy)
|
||||
{
|
||||
int handle = int(proxy - m_pLargeHandles);
|
||||
btAssert((handle >= 0) && (handle < m_maxHandles));
|
||||
if(handle == m_LastLargeHandleIndex)
|
||||
{
|
||||
m_LastLargeHandleIndex--;
|
||||
}
|
||||
proxy->SetNextFree(m_firstFreeLargeHandle);
|
||||
m_firstFreeLargeHandle = handle;
|
||||
proxy->m_clientObject = 0;
|
||||
m_numLargeHandles--;
|
||||
}
|
||||
bool isLargeProxy(const btVector3& aabbMin, const btVector3& aabbMax);
|
||||
bool isLargeProxy(btBroadphaseProxy* proxy);
|
||||
// debug
|
||||
unsigned int m_numPairsAdded;
|
||||
unsigned int m_numPairsRemoved;
|
||||
unsigned int m_numOverflows;
|
||||
//
|
||||
public:
|
||||
btGpu3DGridBroadphase(const btVector3& worldAabbMin,const btVector3& worldAabbMax,
|
||||
int gridSizeX, int gridSizeY, int gridSizeZ,
|
||||
int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody,
|
||||
int maxBodiesPerCell = 8,
|
||||
btScalar cellFactorAABB = btScalar(1.0f));
|
||||
btGpu3DGridBroadphase( btOverlappingPairCache* overlappingPairCache,
|
||||
const btVector3& worldAabbMin,const btVector3& worldAabbMax,
|
||||
int gridSizeX, int gridSizeY, int gridSizeZ,
|
||||
int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody,
|
||||
int maxBodiesPerCell = 8,
|
||||
btScalar cellFactorAABB = btScalar(1.0f));
|
||||
virtual ~btGpu3DGridBroadphase();
|
||||
virtual void calculateOverlappingPairs(btDispatcher* dispatcher);
|
||||
|
||||
virtual btBroadphaseProxy* createProxy(const btVector3& aabbMin, const btVector3& aabbMax,int shapeType,void* userPtr ,short int collisionFilterGroup,short int collisionFilterMask, btDispatcher* dispatcher,void* multiSapProxy);
|
||||
virtual void destroyProxy(btBroadphaseProxy* proxy,btDispatcher* dispatcher);
|
||||
virtual void rayTest(const btVector3& rayFrom,const btVector3& rayTo, btBroadphaseRayCallback& rayCallback);
|
||||
virtual void resetPool(btDispatcher* dispatcher);
|
||||
|
||||
protected:
|
||||
void _initialize( const btVector3& worldAabbMin,const btVector3& worldAabbMax,
|
||||
int gridSizeX, int gridSizeY, int gridSizeZ,
|
||||
int maxSmallProxies, int maxLargeProxies, int maxPairsPerBody,
|
||||
int maxBodiesPerCell = 8,
|
||||
btScalar cellFactorAABB = btScalar(1.0f));
|
||||
void _finalize();
|
||||
void addPairsToCache(btDispatcher* dispatcher);
|
||||
void addLarge2LargePairsToCache(btDispatcher* dispatcher);
|
||||
|
||||
// overrides for CPU version
|
||||
virtual void setParameters(bt3DGridBroadphaseParams* hostParams);
|
||||
virtual void prepareAABB();
|
||||
virtual void calcHashAABB();
|
||||
virtual void sortHash();
|
||||
virtual void findCellStart();
|
||||
virtual void findOverlappingPairs();
|
||||
virtual void findPairsLarge();
|
||||
virtual void computePairCacheChanges();
|
||||
virtual void scanOverlappingPairBuff();
|
||||
virtual void squeezeOverlappingPairBuff();
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#endif //BTGPU3DGRIDBROADPHASE_H
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,430 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
// K E R N E L F U N C T I O N S
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// calculate position in uniform grid
|
||||
BT_GPU___device__ int3 bt3DGrid_calcGridPos(float4 p)
|
||||
{
|
||||
int3 gridPos;
|
||||
gridPos.x = (int)floor((p.x - BT_GPU_params.m_worldOriginX) / BT_GPU_params.m_cellSizeX);
|
||||
gridPos.y = (int)floor((p.y - BT_GPU_params.m_worldOriginY) / BT_GPU_params.m_cellSizeY);
|
||||
gridPos.z = (int)floor((p.z - BT_GPU_params.m_worldOriginZ) / BT_GPU_params.m_cellSizeZ);
|
||||
return gridPos;
|
||||
} // bt3DGrid_calcGridPos()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// calculate address in grid from position (clamping to edges)
|
||||
BT_GPU___device__ uint bt3DGrid_calcGridHash(int3 gridPos)
|
||||
{
|
||||
gridPos.x = BT_GPU_max(0, BT_GPU_min(gridPos.x, (int)BT_GPU_params.m_gridSizeX - 1));
|
||||
gridPos.y = BT_GPU_max(0, BT_GPU_min(gridPos.y, (int)BT_GPU_params.m_gridSizeY - 1));
|
||||
gridPos.z = BT_GPU_max(0, BT_GPU_min(gridPos.z, (int)BT_GPU_params.m_gridSizeZ - 1));
|
||||
return BT_GPU___mul24(BT_GPU___mul24(gridPos.z, BT_GPU_params.m_gridSizeY), BT_GPU_params.m_gridSizeX) + BT_GPU___mul24(gridPos.y, BT_GPU_params.m_gridSizeX) + gridPos.x;
|
||||
} // bt3DGrid_calcGridHash()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// calculate grid hash value for each body using its AABB
|
||||
BT_GPU___global__ void calcHashAABBD(bt3DGrid3F1U* pAABB, uint2* pHash, uint numBodies)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bt3DGrid3F1U bbMin = pAABB[index*2];
|
||||
bt3DGrid3F1U bbMax = pAABB[index*2 + 1];
|
||||
float4 pos;
|
||||
pos.x = (bbMin.fx + bbMax.fx) * 0.5f;
|
||||
pos.y = (bbMin.fy + bbMax.fy) * 0.5f;
|
||||
pos.z = (bbMin.fz + bbMax.fz) * 0.5f;
|
||||
// get address in grid
|
||||
int3 gridPos = bt3DGrid_calcGridPos(pos);
|
||||
uint gridHash = bt3DGrid_calcGridHash(gridPos);
|
||||
// store grid hash and body index
|
||||
pHash[index] = BT_GPU_make_uint2(gridHash, index);
|
||||
} // calcHashAABBD()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___global__ void findCellStartD(uint2* pHash, uint* cellStart, uint numBodies)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint2 sortedData = pHash[index];
|
||||
// Load hash data into shared memory so that we can look
|
||||
// at neighboring body's hash value without loading
|
||||
// two hash values per thread
|
||||
BT_GPU___shared__ uint sharedHash[257];
|
||||
sharedHash[BT_GPU_threadIdx.x+1] = sortedData.x;
|
||||
if((index > 0) && (BT_GPU_threadIdx.x == 0))
|
||||
{
|
||||
// first thread in block must load neighbor body hash
|
||||
volatile uint2 prevData = pHash[index-1];
|
||||
sharedHash[0] = prevData.x;
|
||||
}
|
||||
BT_GPU___syncthreads();
|
||||
if((index == 0) || (sortedData.x != sharedHash[BT_GPU_threadIdx.x]))
|
||||
{
|
||||
cellStart[sortedData.x] = index;
|
||||
}
|
||||
} // findCellStartD()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___device__ uint cudaTestAABBOverlap(bt3DGrid3F1U min0, bt3DGrid3F1U max0, bt3DGrid3F1U min1, bt3DGrid3F1U max1)
|
||||
{
|
||||
return (min0.fx <= max1.fx)&& (min1.fx <= max0.fx) &&
|
||||
(min0.fy <= max1.fy)&& (min1.fy <= max0.fy) &&
|
||||
(min0.fz <= max1.fz)&& (min1.fz <= max0.fz);
|
||||
} // cudaTestAABBOverlap()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___device__ void findPairsInCell( int3 gridPos,
|
||||
uint index,
|
||||
uint2* pHash,
|
||||
uint* pCellStart,
|
||||
bt3DGrid3F1U* pAABB,
|
||||
uint* pPairBuff,
|
||||
uint2* pPairBuffStartCurr,
|
||||
uint numBodies)
|
||||
{
|
||||
if ( (gridPos.x < 0) || (gridPos.x > (int)BT_GPU_params.m_gridSizeX - 1)
|
||||
|| (gridPos.y < 0) || (gridPos.y > (int)BT_GPU_params.m_gridSizeY - 1)
|
||||
|| (gridPos.z < 0) || (gridPos.z > (int)BT_GPU_params.m_gridSizeZ - 1))
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint gridHash = bt3DGrid_calcGridHash(gridPos);
|
||||
// get start of bucket for this cell
|
||||
uint bucketStart = pCellStart[gridHash];
|
||||
if (bucketStart == 0xffffffff)
|
||||
{
|
||||
return; // cell empty
|
||||
}
|
||||
// iterate over bodies in this cell
|
||||
uint2 sortedData = pHash[index];
|
||||
uint unsorted_indx = sortedData.y;
|
||||
bt3DGrid3F1U min0 = BT_GPU_FETCH(pAABB, unsorted_indx*2);
|
||||
bt3DGrid3F1U max0 = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1);
|
||||
uint handleIndex = min0.uw;
|
||||
uint2 start_curr = pPairBuffStartCurr[handleIndex];
|
||||
uint start = start_curr.x;
|
||||
uint curr = start_curr.y;
|
||||
uint2 start_curr_next = pPairBuffStartCurr[handleIndex+1];
|
||||
uint curr_max = start_curr_next.x - start - 1;
|
||||
uint bucketEnd = bucketStart + BT_GPU_params.m_maxBodiesPerCell;
|
||||
bucketEnd = (bucketEnd > numBodies) ? numBodies : bucketEnd;
|
||||
for(uint index2 = bucketStart; index2 < bucketEnd; index2++)
|
||||
{
|
||||
uint2 cellData = pHash[index2];
|
||||
if (cellData.x != gridHash)
|
||||
{
|
||||
break; // no longer in same bucket
|
||||
}
|
||||
uint unsorted_indx2 = cellData.y;
|
||||
if (unsorted_indx2 < unsorted_indx) // check not colliding with self
|
||||
{
|
||||
bt3DGrid3F1U min1 = BT_GPU_FETCH(pAABB, unsorted_indx2*2);
|
||||
bt3DGrid3F1U max1 = BT_GPU_FETCH(pAABB, unsorted_indx2*2 + 1);
|
||||
if(cudaTestAABBOverlap(min0, max0, min1, max1))
|
||||
{
|
||||
uint handleIndex2 = min1.uw;
|
||||
uint k;
|
||||
for(k = 0; k < curr; k++)
|
||||
{
|
||||
uint old_pair = pPairBuff[start+k] & (~BT_3DGRID_PAIR_ANY_FLG);
|
||||
if(old_pair == handleIndex2)
|
||||
{
|
||||
pPairBuff[start+k] |= BT_3DGRID_PAIR_FOUND_FLG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k == curr)
|
||||
{
|
||||
if(curr >= curr_max)
|
||||
{ // not a good solution, but let's avoid crash
|
||||
break;
|
||||
}
|
||||
pPairBuff[start+curr] = handleIndex2 | BT_3DGRID_PAIR_NEW_FLG;
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, curr);
|
||||
return;
|
||||
} // findPairsInCell()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___global__ void findOverlappingPairsD( bt3DGrid3F1U* pAABB, uint2* pHash, uint* pCellStart,
|
||||
uint* pPairBuff, uint2* pPairBuffStartCurr, uint numBodies)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint2 sortedData = pHash[index];
|
||||
uint unsorted_indx = sortedData.y;
|
||||
bt3DGrid3F1U bbMin = BT_GPU_FETCH(pAABB, unsorted_indx*2);
|
||||
bt3DGrid3F1U bbMax = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1);
|
||||
float4 pos;
|
||||
pos.x = (bbMin.fx + bbMax.fx) * 0.5f;
|
||||
pos.y = (bbMin.fy + bbMax.fy) * 0.5f;
|
||||
pos.z = (bbMin.fz + bbMax.fz) * 0.5f;
|
||||
// get address in grid
|
||||
int3 gridPos = bt3DGrid_calcGridPos(pos);
|
||||
// examine only neighbouring cells
|
||||
for(int z=-1; z<=1; z++) {
|
||||
for(int y=-1; y<=1; y++) {
|
||||
for(int x=-1; x<=1; x++) {
|
||||
findPairsInCell(gridPos + BT_GPU_make_int3(x, y, z), index, pHash, pCellStart, pAABB, pPairBuff, pPairBuffStartCurr, numBodies);
|
||||
}
|
||||
}
|
||||
}
|
||||
} // findOverlappingPairsD()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___global__ void findPairsLargeD( bt3DGrid3F1U* pAABB, uint2* pHash, uint* pCellStart, uint* pPairBuff,
|
||||
uint2* pPairBuffStartCurr, uint numBodies, uint numLarge)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
uint2 sortedData = pHash[index];
|
||||
uint unsorted_indx = sortedData.y;
|
||||
bt3DGrid3F1U min0 = BT_GPU_FETCH(pAABB, unsorted_indx*2);
|
||||
bt3DGrid3F1U max0 = BT_GPU_FETCH(pAABB, unsorted_indx*2 + 1);
|
||||
uint handleIndex = min0.uw;
|
||||
uint2 start_curr = pPairBuffStartCurr[handleIndex];
|
||||
uint start = start_curr.x;
|
||||
uint curr = start_curr.y;
|
||||
uint2 start_curr_next = pPairBuffStartCurr[handleIndex+1];
|
||||
uint curr_max = start_curr_next.x - start - 1;
|
||||
for(uint i = 0; i < numLarge; i++)
|
||||
{
|
||||
uint indx2 = numBodies + i;
|
||||
bt3DGrid3F1U min1 = BT_GPU_FETCH(pAABB, indx2*2);
|
||||
bt3DGrid3F1U max1 = BT_GPU_FETCH(pAABB, indx2*2 + 1);
|
||||
if(cudaTestAABBOverlap(min0, max0, min1, max1))
|
||||
{
|
||||
uint k;
|
||||
uint handleIndex2 = min1.uw;
|
||||
for(k = 0; k < curr; k++)
|
||||
{
|
||||
uint old_pair = pPairBuff[start+k] & (~BT_3DGRID_PAIR_ANY_FLG);
|
||||
if(old_pair == handleIndex2)
|
||||
{
|
||||
pPairBuff[start+k] |= BT_3DGRID_PAIR_FOUND_FLG;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(k == curr)
|
||||
{
|
||||
pPairBuff[start+curr] = handleIndex2 | BT_3DGRID_PAIR_NEW_FLG;
|
||||
if(curr >= curr_max)
|
||||
{ // not a good solution, but let's avoid crash
|
||||
break;
|
||||
}
|
||||
curr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, curr);
|
||||
return;
|
||||
} // findPairsLargeD()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___global__ void computePairCacheChangesD(uint* pPairBuff, uint2* pPairBuffStartCurr,
|
||||
uint* pPairScan, bt3DGrid3F1U* pAABB, uint numBodies)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bt3DGrid3F1U bbMin = pAABB[index * 2];
|
||||
uint handleIndex = bbMin.uw;
|
||||
uint2 start_curr = pPairBuffStartCurr[handleIndex];
|
||||
uint start = start_curr.x;
|
||||
uint curr = start_curr.y;
|
||||
uint *pInp = pPairBuff + start;
|
||||
uint num_changes = 0;
|
||||
for(uint k = 0; k < curr; k++, pInp++)
|
||||
{
|
||||
if(!((*pInp) & BT_3DGRID_PAIR_FOUND_FLG))
|
||||
{
|
||||
num_changes++;
|
||||
}
|
||||
}
|
||||
pPairScan[index+1] = num_changes;
|
||||
} // computePairCacheChangesD()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
BT_GPU___global__ void squeezeOverlappingPairBuffD(uint* pPairBuff, uint2* pPairBuffStartCurr, uint* pPairScan,
|
||||
uint* pPairOut, bt3DGrid3F1U* pAABB, uint numBodies)
|
||||
{
|
||||
int index = BT_GPU___mul24(BT_GPU_blockIdx.x, BT_GPU_blockDim.x) + BT_GPU_threadIdx.x;
|
||||
if(index >= (int)numBodies)
|
||||
{
|
||||
return;
|
||||
}
|
||||
bt3DGrid3F1U bbMin = pAABB[index * 2];
|
||||
uint handleIndex = bbMin.uw;
|
||||
uint2 start_curr = pPairBuffStartCurr[handleIndex];
|
||||
uint start = start_curr.x;
|
||||
uint curr = start_curr.y;
|
||||
uint* pInp = pPairBuff + start;
|
||||
uint* pOut = pPairOut + pPairScan[index];
|
||||
uint* pOut2 = pInp;
|
||||
uint num = 0;
|
||||
for(uint k = 0; k < curr; k++, pInp++)
|
||||
{
|
||||
if(!((*pInp) & BT_3DGRID_PAIR_FOUND_FLG))
|
||||
{
|
||||
*pOut = *pInp;
|
||||
pOut++;
|
||||
}
|
||||
if((*pInp) & BT_3DGRID_PAIR_ANY_FLG)
|
||||
{
|
||||
*pOut2 = (*pInp) & (~BT_3DGRID_PAIR_ANY_FLG);
|
||||
pOut2++;
|
||||
num++;
|
||||
}
|
||||
}
|
||||
pPairBuffStartCurr[handleIndex] = BT_GPU_make_uint2(start, num);
|
||||
} // squeezeOverlappingPairBuffD()
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
// E N D O F K E R N E L F U N C T I O N S
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(calcHashAABB)(bt3DGrid3F1U* pAABB, unsigned int* hash, unsigned int numBodies)
|
||||
{
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads);
|
||||
// execute the kernel
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, calcHashAABBD, (pAABB, (uint2*)hash, numBodies));
|
||||
// check if kernel invocation generated an error
|
||||
BT_GPU_CHECK_ERROR("calcHashAABBD kernel execution failed");
|
||||
} // calcHashAABB()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(findCellStart(unsigned int* hash, unsigned int* cellStart, unsigned int numBodies, unsigned int numCells))
|
||||
{
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads);
|
||||
BT_GPU_SAFE_CALL(BT_GPU_Memset(cellStart, 0xffffffff, numCells*sizeof(uint)));
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, findCellStartD, ((uint2*)hash, (uint*)cellStart, numBodies));
|
||||
BT_GPU_CHECK_ERROR("Kernel execution failed: findCellStartD");
|
||||
} // findCellStart()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(findOverlappingPairs(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies))
|
||||
{
|
||||
#if B_CUDA_USE_TEX
|
||||
BT_GPU_SAFE_CALL(cudaBindTexture(0, pAABBTex, pAABB, numBodies * 2 * sizeof(bt3DGrid3F1U)));
|
||||
#endif
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 64, numBlocks, numThreads);
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, findOverlappingPairsD, (pAABB,(uint2*)pHash,(uint*)pCellStart,(uint*)pPairBuff,(uint2*)pPairBuffStartCurr,numBodies));
|
||||
BT_GPU_CHECK_ERROR("Kernel execution failed: bt_CudaFindOverlappingPairsD");
|
||||
#if B_CUDA_USE_TEX
|
||||
BT_GPU_SAFE_CALL(cudaUnbindTexture(pAABBTex));
|
||||
#endif
|
||||
} // findOverlappingPairs()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(findPairsLarge(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies, unsigned int numLarge))
|
||||
{
|
||||
#if B_CUDA_USE_TEX
|
||||
BT_GPU_SAFE_CALL(cudaBindTexture(0, pAABBTex, pAABB, (numBodies+numLarge) * 2 * sizeof(bt3DGrid3F1U)));
|
||||
#endif
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 64, numBlocks, numThreads);
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, findPairsLargeD, (pAABB,(uint2*)pHash,(uint*)pCellStart,(uint*)pPairBuff,(uint2*)pPairBuffStartCurr,numBodies,numLarge));
|
||||
BT_GPU_CHECK_ERROR("Kernel execution failed: btCuda_findPairsLargeD");
|
||||
#if B_CUDA_USE_TEX
|
||||
BT_GPU_SAFE_CALL(cudaUnbindTexture(pAABBTex));
|
||||
#endif
|
||||
} // findPairsLarge()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(computePairCacheChanges(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, bt3DGrid3F1U* pAABB, unsigned int numBodies))
|
||||
{
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads);
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, computePairCacheChangesD, ((uint*)pPairBuff,(uint2*)pPairBuffStartCurr,(uint*)pPairScan,pAABB,numBodies));
|
||||
BT_GPU_CHECK_ERROR("Kernel execution failed: btCudaComputePairCacheChangesD");
|
||||
} // computePairCacheChanges()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(squeezeOverlappingPairBuff(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, unsigned int* pPairOut, bt3DGrid3F1U* pAABB, unsigned int numBodies))
|
||||
{
|
||||
int numThreads, numBlocks;
|
||||
BT_GPU_PREF(computeGridSize)(numBodies, 256, numBlocks, numThreads);
|
||||
BT_GPU_EXECKERNEL(numBlocks, numThreads, squeezeOverlappingPairBuffD, ((uint*)pPairBuff,(uint2*)pPairBuffStartCurr,(uint*)pPairScan,(uint*)pPairOut,pAABB,numBodies));
|
||||
BT_GPU_CHECK_ERROR("Kernel execution failed: btCudaSqueezeOverlappingPairBuffD");
|
||||
} // btCuda_squeezeOverlappingPairBuff()
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
||||
} // extern "C"
|
||||
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
//------------------------------------------------------------------------------------------------
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// Shared definitions for GPU-based 3D Grid collision detection broadphase
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// Keep this file free from Bullet headers
|
||||
// it is included into both CUDA and CPU code
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BTGPU3DGRIDBROADPHASESHAREDDEFS_H
|
||||
#define BTGPU3DGRIDBROADPHASESHAREDDEFS_H
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "btGpu3DGridBroadphaseSharedTypes.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
void BT_GPU_PREF(calcHashAABB)(bt3DGrid3F1U* pAABB, unsigned int* hash, unsigned int numBodies);
|
||||
|
||||
void BT_GPU_PREF(findCellStart)(unsigned int* hash, unsigned int* cellStart, unsigned int numBodies, unsigned int numCells);
|
||||
|
||||
void BT_GPU_PREF(findOverlappingPairs)(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies);
|
||||
|
||||
void BT_GPU_PREF(findPairsLarge)(bt3DGrid3F1U* pAABB, unsigned int* pHash, unsigned int* pCellStart, unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int numBodies, unsigned int numLarge);
|
||||
|
||||
void BT_GPU_PREF(computePairCacheChanges)(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, bt3DGrid3F1U* pAABB, unsigned int numBodies);
|
||||
|
||||
void BT_GPU_PREF(squeezeOverlappingPairBuff)(unsigned int* pPairBuff, unsigned int* pPairBuffStartCurr, unsigned int* pPairScan, unsigned int* pPairOut, bt3DGrid3F1U* pAABB, unsigned int numBodies);
|
||||
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
} // extern "C"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // BTGPU3DGRIDBROADPHASESHAREDDEFS_H
|
||||
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// Shared definitions for GPU-based 3D Grid collision detection broadphase
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// Keep this file free from Bullet headers
|
||||
// it is included into both CUDA and CPU code
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#ifndef BTGPU3DGRIDBROADPHASESHAREDTYPES_H
|
||||
#define BTGPU3DGRIDBROADPHASESHAREDTYPES_H
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#define BT_3DGRID_PAIR_FOUND_FLG (0x40000000)
|
||||
#define BT_3DGRID_PAIR_NEW_FLG (0x20000000)
|
||||
#define BT_3DGRID_PAIR_ANY_FLG (BT_3DGRID_PAIR_FOUND_FLG | BT_3DGRID_PAIR_NEW_FLG)
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
struct bt3DGridBroadphaseParams
|
||||
{
|
||||
unsigned int m_gridSizeX;
|
||||
unsigned int m_gridSizeY;
|
||||
unsigned int m_gridSizeZ;
|
||||
unsigned int m_numCells;
|
||||
float m_worldOriginX;
|
||||
float m_worldOriginY;
|
||||
float m_worldOriginZ;
|
||||
float m_cellSizeX;
|
||||
float m_cellSizeY;
|
||||
float m_cellSizeZ;
|
||||
unsigned int m_numBodies;
|
||||
unsigned int m_maxBodiesPerCell;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
struct bt3DGrid3F1U
|
||||
{
|
||||
float fx;
|
||||
float fy;
|
||||
float fz;
|
||||
unsigned int uw;
|
||||
};
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#endif // BTGPU3DGRIDBROADPHASESHAREDTYPES_H
|
||||
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// definitions for "GPU on CPU" code
|
||||
|
||||
|
||||
#ifndef BT_GPU_DEFINES_H
|
||||
#define BT_GPU_DEFINES_H
|
||||
|
||||
typedef unsigned int uint;
|
||||
|
||||
struct int2
|
||||
{
|
||||
int x, y;
|
||||
};
|
||||
|
||||
struct uint2
|
||||
{
|
||||
unsigned int x, y;
|
||||
};
|
||||
|
||||
struct int3
|
||||
{
|
||||
int x, y, z;
|
||||
};
|
||||
|
||||
struct uint3
|
||||
{
|
||||
unsigned int x, y, z;
|
||||
};
|
||||
|
||||
struct float4
|
||||
{
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
struct float3
|
||||
{
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
|
||||
#define BT_GPU___device__ inline
|
||||
#define BT_GPU___devdata__
|
||||
#define BT_GPU___constant__
|
||||
#define BT_GPU_max(a, b) ((a) > (b) ? (a) : (b))
|
||||
#define BT_GPU_min(a, b) ((a) < (b) ? (a) : (b))
|
||||
#define BT_GPU_params s3DGridBroadphaseParams
|
||||
#define BT_GPU___mul24(a, b) ((a)*(b))
|
||||
#define BT_GPU___global__ inline
|
||||
#define BT_GPU___shared__ static
|
||||
#define BT_GPU___syncthreads()
|
||||
#define CUDART_PI_F SIMD_PI
|
||||
|
||||
static inline uint2 bt3dGrid_make_uint2(unsigned int x, unsigned int y)
|
||||
{
|
||||
uint2 t; t.x = x; t.y = y; return t;
|
||||
}
|
||||
#define BT_GPU_make_uint2(x, y) bt3dGrid_make_uint2(x, y)
|
||||
|
||||
static inline int3 bt3dGrid_make_int3(int x, int y, int z)
|
||||
{
|
||||
int3 t; t.x = x; t.y = y; t.z = z; return t;
|
||||
}
|
||||
#define BT_GPU_make_int3(x, y, z) bt3dGrid_make_int3(x, y, z)
|
||||
|
||||
static inline float3 bt3dGrid_make_float3(float x, float y, float z)
|
||||
{
|
||||
float3 t; t.x = x; t.y = y; t.z = z; return t;
|
||||
}
|
||||
#define BT_GPU_make_float3(x, y, z) bt3dGrid_make_float3(x, y, z)
|
||||
|
||||
static inline float3 bt3dGrid_make_float34(float4 f)
|
||||
{
|
||||
float3 t; t.x = f.x; t.y = f.y; t.z = f.z; return t;
|
||||
}
|
||||
#define BT_GPU_make_float34(f) bt3dGrid_make_float34(f)
|
||||
|
||||
static inline float3 bt3dGrid_make_float31(float f)
|
||||
{
|
||||
float3 t; t.x = t.y = t.z = f; return t;
|
||||
}
|
||||
#define BT_GPU_make_float31(x) bt3dGrid_make_float31(x)
|
||||
|
||||
static inline float4 bt3dGrid_make_float42(float3 v, float f)
|
||||
{
|
||||
float4 t; t.x = v.x; t.y = v.y; t.z = v.z; t.w = f; return t;
|
||||
}
|
||||
#define BT_GPU_make_float42(a, b) bt3dGrid_make_float42(a, b)
|
||||
|
||||
static inline float4 bt3dGrid_make_float44(float a, float b, float c, float d)
|
||||
{
|
||||
float4 t; t.x = a; t.y = b; t.z = c; t.w = d; return t;
|
||||
}
|
||||
#define BT_GPU_make_float44(a, b, c, d) bt3dGrid_make_float44(a, b, c, d)
|
||||
|
||||
inline int3 operator+(int3 a, int3 b)
|
||||
{
|
||||
return bt3dGrid_make_int3(a.x + b.x, a.y + b.y, a.z + b.z);
|
||||
}
|
||||
|
||||
inline float4 operator+(const float4& a, const float4& b)
|
||||
{
|
||||
float4 r; r.x = a.x+b.x; r.y = a.y+b.y; r.z = a.z+b.z; r.w = a.w+b.w; return r;
|
||||
}
|
||||
inline float4 operator*(const float4& a, float fact)
|
||||
{
|
||||
float4 r; r.x = a.x*fact; r.y = a.y*fact; r.z = a.z*fact; r.w = a.w*fact; return r;
|
||||
}
|
||||
inline float4 operator*(float fact, float4& a)
|
||||
{
|
||||
return (a * fact);
|
||||
}
|
||||
inline float4& operator*=(float4& a, float fact)
|
||||
{
|
||||
a = fact * a;
|
||||
return a;
|
||||
}
|
||||
inline float4& operator+=(float4& a, const float4& b)
|
||||
{
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
|
||||
inline float3 operator+(const float3& a, const float3& b)
|
||||
{
|
||||
float3 r; r.x = a.x+b.x; r.y = a.y+b.y; r.z = a.z+b.z; return r;
|
||||
}
|
||||
inline float3 operator-(const float3& a, const float3& b)
|
||||
{
|
||||
float3 r; r.x = a.x-b.x; r.y = a.y-b.y; r.z = a.z-b.z; return r;
|
||||
}
|
||||
static inline float bt3dGrid_dot(float3& a, float3& b)
|
||||
{
|
||||
return a.x*b.x+a.y*b.y+a.z*b.z;
|
||||
}
|
||||
#define BT_GPU_dot(a,b) bt3dGrid_dot(a,b)
|
||||
|
||||
static inline float bt3dGrid_dot4(float4& a, float4& b)
|
||||
{
|
||||
return a.x*b.x+a.y*b.y+a.z*b.z+a.w*b.w;
|
||||
}
|
||||
#define BT_GPU_dot4(a,b) bt3dGrid_dot4(a,b)
|
||||
|
||||
static inline float3 bt3dGrid_cross(const float3& a, const float3& b)
|
||||
{
|
||||
float3 r; r.x = a.y*b.z-a.z*b.y; r.y = -a.x*b.z+a.z*b.x; r.z = a.x*b.y-a.y*b.x; return r;
|
||||
}
|
||||
#define BT_GPU_cross(a,b) bt3dGrid_cross(a,b)
|
||||
|
||||
|
||||
inline float3 operator*(const float3& a, float fact)
|
||||
{
|
||||
float3 r; r.x = a.x*fact; r.y = a.y*fact; r.z = a.z*fact; return r;
|
||||
}
|
||||
|
||||
|
||||
inline float3& operator+=(float3& a, const float3& b)
|
||||
{
|
||||
a = a + b;
|
||||
return a;
|
||||
}
|
||||
inline float3& operator-=(float3& a, const float3& b)
|
||||
{
|
||||
a = a - b;
|
||||
return a;
|
||||
}
|
||||
inline float3& operator*=(float3& a, float fact)
|
||||
{
|
||||
a = a * fact;
|
||||
return a;
|
||||
}
|
||||
inline float3 operator-(const float3& v)
|
||||
{
|
||||
float3 r; r.x = -v.x; r.y = -v.y; r.z = -v.z; return r;
|
||||
}
|
||||
|
||||
|
||||
#define BT_GPU_FETCH(a, b) a[b]
|
||||
#define BT_GPU_FETCH4(a, b) a[b]
|
||||
#define BT_GPU_PREF(func) btGpu_##func
|
||||
#define BT_GPU_SAFE_CALL(func) func
|
||||
#define BT_GPU_Memset memset
|
||||
#define BT_GPU_MemcpyToSymbol(a, b, c) memcpy(&a, b, c)
|
||||
#define BT_GPU_BindTexture(a, b, c, d)
|
||||
#define BT_GPU_UnbindTexture(a)
|
||||
|
||||
static uint2 s_blockIdx, s_blockDim, s_threadIdx;
|
||||
#define BT_GPU_blockIdx s_blockIdx
|
||||
#define BT_GPU_blockDim s_blockDim
|
||||
#define BT_GPU_threadIdx s_threadIdx
|
||||
#define BT_GPU_EXECKERNEL(numb, numt, kfunc, args) {s_blockDim.x=numt;for(int nb=0;nb<numb;nb++){s_blockIdx.x=nb;for(int nt=0;nt<numt;nt++){s_threadIdx.x=nt;kfunc args;}}}
|
||||
|
||||
#define BT_GPU_CHECK_ERROR(s)
|
||||
|
||||
|
||||
#endif //BT_GPU_DEFINES_H
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2009 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// Shared code for GPU-based utilities
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// Keep this file free from Bullet headers
|
||||
// will be compiled by both CPU and CUDA compilers
|
||||
// file with definitions of BT_GPU_xxx should be included first
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
#include "btGpuUtilsSharedDefs.h"
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
//Round a / b to nearest higher integer value
|
||||
int BT_GPU_PREF(iDivUp)(int a, int b)
|
||||
{
|
||||
return (a % b != 0) ? (a / b + 1) : (a / b);
|
||||
} // iDivUp()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
// compute grid and thread block size for a given number of elements
|
||||
void BT_GPU_PREF(computeGridSize)(int n, int blockSize, int &numBlocks, int &numThreads)
|
||||
{
|
||||
numThreads = BT_GPU_min(blockSize, n);
|
||||
numBlocks = BT_GPU_PREF(iDivUp)(n, numThreads);
|
||||
} // computeGridSize()
|
||||
|
||||
//----------------------------------------------------------------------------------------
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library, http://bulletphysics.org
|
||||
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
|
||||
|
||||
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.
|
||||
*/
|
||||
|
||||
// Shared definitions for GPU-based utilities
|
||||
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
// Keep this file free from Bullet headers
|
||||
// it is included into both CUDA and CPU code
|
||||
// file with definitions of BT_GPU_xxx should be included first
|
||||
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||||
|
||||
|
||||
#ifndef BTGPUUTILSDHAREDDEFS_H
|
||||
#define BTGPUUTILSDHAREDDEFS_H
|
||||
|
||||
|
||||
extern "C"
|
||||
{
|
||||
|
||||
|
||||
//Round a / b to nearest higher integer value
|
||||
int BT_GPU_PREF(iDivUp)(int a, int b);
|
||||
|
||||
// compute grid and thread block size for a given number of elements
|
||||
void BT_GPU_PREF(computeGridSize)(int n, int blockSize, int &numBlocks, int &numThreads);
|
||||
|
||||
void BT_GPU_PREF(allocateArray)(void** devPtr, unsigned int size);
|
||||
void BT_GPU_PREF(freeArray)(void* devPtr);
|
||||
void BT_GPU_PREF(copyArrayFromDevice)(void* host, const void* device, unsigned int size);
|
||||
void BT_GPU_PREF(copyArrayToDevice)(void* device, const void* host, unsigned int size);
|
||||
void BT_GPU_PREF(registerGLBufferObject(unsigned int vbo));
|
||||
void* BT_GPU_PREF(mapGLBufferObject(unsigned int vbo));
|
||||
void BT_GPU_PREF(unmapGLBufferObject(unsigned int vbo));
|
||||
|
||||
|
||||
} // extern "C"
|
||||
|
||||
|
||||
#endif // BTGPUUTILSDHAREDDEFS_H
|
||||
|
||||
|
|
@ -0,0 +1,283 @@
|
|||
/*
|
||||
Copyright (C) 2010 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
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_PARALLEL_CONSTRAINT_SOLVER_H
|
||||
#define __BT_PARALLEL_CONSTRAINT_SOLVER_H
|
||||
|
||||
#include "BulletDynamics/ConstraintSolver/btSequentialImpulseConstraintSolver.h"
|
||||
|
||||
|
||||
|
||||
|
||||
#include "LinearMath/btScalar.h"
|
||||
#include "PlatformDefinitions.h"
|
||||
|
||||
|
||||
#define PFX_MAX_SOLVER_PHASES 64
|
||||
#define PFX_MAX_SOLVER_BATCHES 16
|
||||
#define PFX_MAX_SOLVER_PAIRS 128
|
||||
#define PFX_MIN_SOLVER_PAIRS 16
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
ATTRIBUTE_ALIGNED128(struct) PfxParallelBatch {
|
||||
#else
|
||||
ATTRIBUTE_ALIGNED16(struct) PfxParallelBatch {
|
||||
#endif
|
||||
uint16_t pairIndices[PFX_MAX_SOLVER_PAIRS];
|
||||
};
|
||||
|
||||
#ifdef __CELLOS_LV2__
|
||||
ATTRIBUTE_ALIGNED128(struct) PfxParallelGroup {
|
||||
#else
|
||||
ATTRIBUTE_ALIGNED16(struct) PfxParallelGroup {
|
||||
#endif
|
||||
uint16_t numPhases;
|
||||
uint16_t numBatches[PFX_MAX_SOLVER_PHASES];
|
||||
uint16_t numPairs[PFX_MAX_SOLVER_PHASES*PFX_MAX_SOLVER_BATCHES];
|
||||
};
|
||||
|
||||
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) PfxSortData16 {
|
||||
union {
|
||||
uint8_t i8data[16];
|
||||
uint16_t i16data[8];
|
||||
uint32_t i32data[4];
|
||||
#ifdef __SPU__
|
||||
vec_uint4 vdata;
|
||||
#endif
|
||||
};
|
||||
|
||||
#ifdef __SPU__
|
||||
void set8(int elem,uint8_t data) {vdata=(vec_uint4)spu_insert(data,(vec_uchar16)vdata,elem);}
|
||||
void set16(int elem,uint16_t data) {vdata=(vec_uint4)spu_insert(data,(vec_ushort8)vdata,elem);}
|
||||
void set32(int elem,uint32_t data) {vdata=(vec_uint4)spu_insert(data,(vec_uint4)vdata,elem);}
|
||||
uint8_t get8(int elem) const {return spu_extract((vec_uchar16)vdata,elem);}
|
||||
uint16_t get16(int elem) const {return spu_extract((vec_ushort8)vdata,elem);}
|
||||
uint32_t get32(int elem) const {return spu_extract((vec_uint4)vdata,elem);}
|
||||
#else
|
||||
void set8(int elem,uint8_t data) {i8data[elem] = data;}
|
||||
void set16(int elem,uint16_t data) {i16data[elem] = data;}
|
||||
void set32(int elem,uint32_t data) {i32data[elem] = data;}
|
||||
uint8_t get8(int elem) const {return i8data[elem];}
|
||||
uint16_t get16(int elem) const {return i16data[elem];}
|
||||
uint32_t get32(int elem) const {return i32data[elem];}
|
||||
#endif
|
||||
};
|
||||
|
||||
typedef PfxSortData16 PfxConstraintPair;
|
||||
|
||||
|
||||
//J PfxBroadphasePair‚Æ‹¤’Ê
|
||||
|
||||
SIMD_FORCE_INLINE void pfxSetConstraintId(PfxConstraintPair &pair,uint32_t i) {pair.set32(2,i);}
|
||||
SIMD_FORCE_INLINE void pfxSetNumConstraints(PfxConstraintPair &pair,uint8_t n) {pair.set8(7,n);}
|
||||
|
||||
SIMD_FORCE_INLINE uint32_t pfxGetConstraintId1(const PfxConstraintPair &pair) {return pair.get32(2);}
|
||||
SIMD_FORCE_INLINE uint8_t pfxGetNumConstraints(const PfxConstraintPair &pair) {return pair.get8(7);}
|
||||
|
||||
typedef PfxSortData16 PfxBroadphasePair;
|
||||
|
||||
SIMD_FORCE_INLINE void pfxSetRigidBodyIdA(PfxBroadphasePair &pair,uint16_t i) {pair.set16(0,i);}
|
||||
SIMD_FORCE_INLINE void pfxSetRigidBodyIdB(PfxBroadphasePair &pair,uint16_t i) {pair.set16(1,i);}
|
||||
SIMD_FORCE_INLINE void pfxSetMotionMaskA(PfxBroadphasePair &pair,uint8_t i) {pair.set8(4,i);}
|
||||
SIMD_FORCE_INLINE void pfxSetMotionMaskB(PfxBroadphasePair &pair,uint8_t i) {pair.set8(5,i);}
|
||||
SIMD_FORCE_INLINE void pfxSetBroadphaseFlag(PfxBroadphasePair &pair,uint8_t f) {pair.set8(6,(pair.get8(6)&0xf0)|(f&0x0f));}
|
||||
SIMD_FORCE_INLINE void pfxSetActive(PfxBroadphasePair &pair,bool b) {pair.set8(6,(pair.get8(6)&0x0f)|((b?1:0)<<4));}
|
||||
SIMD_FORCE_INLINE void pfxSetContactId(PfxBroadphasePair &pair,uint32_t i) {pair.set32(2,i);}
|
||||
|
||||
SIMD_FORCE_INLINE uint16_t pfxGetRigidBodyIdA(const PfxBroadphasePair &pair) {return pair.get16(0);}
|
||||
SIMD_FORCE_INLINE uint16_t pfxGetRigidBodyIdB(const PfxBroadphasePair &pair) {return pair.get16(1);}
|
||||
SIMD_FORCE_INLINE uint8_t pfxGetMotionMaskA(const PfxBroadphasePair &pair) {return pair.get8(4);}
|
||||
SIMD_FORCE_INLINE uint8_t pfxGetMotionMaskB(const PfxBroadphasePair &pair) {return pair.get8(5);}
|
||||
SIMD_FORCE_INLINE uint8_t pfxGetBroadphaseFlag(const PfxBroadphasePair &pair) {return pair.get8(6)&0x0f;}
|
||||
SIMD_FORCE_INLINE bool pfxGetActive(const PfxBroadphasePair &pair) {return (pair.get8(6)>>4)!=0;}
|
||||
SIMD_FORCE_INLINE uint32_t pfxGetContactId1(const PfxBroadphasePair &pair) {return pair.get32(2);}
|
||||
|
||||
|
||||
|
||||
#if defined(__PPU__) || defined (__SPU__)
|
||||
ATTRIBUTE_ALIGNED128(struct) PfxSolverBody {
|
||||
#else
|
||||
ATTRIBUTE_ALIGNED16(struct) PfxSolverBody {
|
||||
#endif
|
||||
vmVector3 mDeltaLinearVelocity;
|
||||
vmVector3 mDeltaAngularVelocity;
|
||||
vmMatrix3 mInertiaInv;
|
||||
vmQuat mOrientation;
|
||||
float mMassInv;
|
||||
float friction;
|
||||
float restitution;
|
||||
float unused;
|
||||
float unused2;
|
||||
float unused3;
|
||||
float unused4;
|
||||
float unused5;
|
||||
};
|
||||
|
||||
|
||||
#ifdef __PPU__
|
||||
#include "SpuDispatch/BulletPE2ConstraintSolverSpursSupport.h"
|
||||
#endif
|
||||
|
||||
static SIMD_FORCE_INLINE vmVector3 btReadVector3(const double* p)
|
||||
{
|
||||
float tmp[3] = {float(p[0]),float(p[1]),float(p[2])};
|
||||
vmVector3 v;
|
||||
loadXYZ(v, tmp);
|
||||
return v;
|
||||
}
|
||||
|
||||
static SIMD_FORCE_INLINE vmQuat btReadQuat(const double* p)
|
||||
{
|
||||
float tmp[4] = {float(p[0]),float(p[1]),float(p[2]),float(p[4])};
|
||||
vmQuat vq;
|
||||
loadXYZW(vq, tmp);
|
||||
return vq;
|
||||
}
|
||||
|
||||
static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, double* p)
|
||||
{
|
||||
float tmp[3];
|
||||
vmVector3 v = src;
|
||||
storeXYZ(v, tmp);
|
||||
p[0] = tmp[0];
|
||||
p[1] = tmp[1];
|
||||
p[2] = tmp[2];
|
||||
}
|
||||
|
||||
|
||||
static SIMD_FORCE_INLINE vmVector3 btReadVector3(const float* p)
|
||||
{
|
||||
vmVector3 v;
|
||||
loadXYZ(v, p);
|
||||
return v;
|
||||
}
|
||||
|
||||
static SIMD_FORCE_INLINE vmQuat btReadQuat(const float* p)
|
||||
{
|
||||
vmQuat vq;
|
||||
loadXYZW(vq, p);
|
||||
return vq;
|
||||
}
|
||||
|
||||
static SIMD_FORCE_INLINE void btStoreVector3(const vmVector3 &src, float* p)
|
||||
{
|
||||
vmVector3 v = src;
|
||||
storeXYZ(v, p);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
class btPersistentManifold;
|
||||
|
||||
enum {
|
||||
PFX_CONSTRAINT_SOLVER_CMD_SETUP_SOLVER_BODIES,
|
||||
PFX_CONSTRAINT_SOLVER_CMD_SETUP_CONTACT_CONSTRAINTS,
|
||||
PFX_CONSTRAINT_SOLVER_CMD_SETUP_JOINT_CONSTRAINTS,
|
||||
PFX_CONSTRAINT_SOLVER_CMD_SOLVE_CONSTRAINTS,
|
||||
PFX_CONSTRAINT_SOLVER_CMD_POST_SOLVER
|
||||
};
|
||||
|
||||
|
||||
struct PfxSetupContactConstraintsIO {
|
||||
PfxConstraintPair *offsetContactPairs;
|
||||
uint32_t numContactPairs1;
|
||||
class TrbState *offsetRigStates;
|
||||
struct PfxSolverBody *offsetSolverBodies;
|
||||
uint32_t numRigidBodies;
|
||||
float separateBias;
|
||||
float timeStep;
|
||||
class btCriticalSection* criticalSection;
|
||||
};
|
||||
|
||||
|
||||
|
||||
struct PfxSolveConstraintsIO {
|
||||
PfxParallelGroup *contactParallelGroup;
|
||||
PfxParallelBatch *contactParallelBatches;
|
||||
PfxConstraintPair *contactPairs;
|
||||
uint32_t numContactPairs;
|
||||
btPersistentManifold *offsetContactManifolds;
|
||||
PfxParallelGroup *jointParallelGroup;
|
||||
PfxParallelBatch *jointParallelBatches;
|
||||
PfxConstraintPair *jointPairs;
|
||||
uint32_t numJointPairs;
|
||||
TrbState *offsetRigStates;
|
||||
PfxSolverBody *offsetSolverBodies;
|
||||
uint32_t numRigidBodies;
|
||||
uint32_t iteration;
|
||||
|
||||
uint32_t taskId;
|
||||
|
||||
class btBarrier* barrier;
|
||||
|
||||
};
|
||||
|
||||
struct PfxPostSolverIO {
|
||||
TrbState *states;
|
||||
PfxSolverBody *solverBodies;
|
||||
uint32_t numRigidBodies;
|
||||
};
|
||||
|
||||
ATTRIBUTE_ALIGNED16(struct) btConstraintSolverIO {
|
||||
uint8_t cmd;
|
||||
union {
|
||||
PfxSetupContactConstraintsIO setupContactConstraints;
|
||||
PfxSolveConstraintsIO solveConstraints;
|
||||
PfxPostSolverIO postSolver;
|
||||
};
|
||||
|
||||
//SPU only
|
||||
uint32_t barrierAddr2;
|
||||
uint32_t criticalsectionAddr2;
|
||||
uint32_t maxTasks1;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
void SolverThreadFunc(void* userPtr,void* lsMemory);
|
||||
void* SolverlsMemoryFunc();
|
||||
///The btParallelConstraintSolver performs computations on constraint rows in parallel
|
||||
///Using the cross-platform threading it supports Windows, Linux, Mac OSX and PlayStation 3 Cell SPUs
|
||||
class btParallelConstraintSolver : public btSequentialImpulseConstraintSolver
|
||||
{
|
||||
|
||||
protected:
|
||||
struct btParallelSolverMemoryCache* m_memoryCache;
|
||||
|
||||
class btThreadSupportInterface* m_solverThreadSupport;
|
||||
|
||||
struct btConstraintSolverIO* m_solverIO;
|
||||
class btBarrier* m_barrier;
|
||||
class btCriticalSection* m_criticalSection;
|
||||
|
||||
|
||||
public:
|
||||
|
||||
btParallelConstraintSolver(class btThreadSupportInterface* solverThreadSupport);
|
||||
|
||||
virtual ~btParallelConstraintSolver();
|
||||
|
||||
virtual btScalar solveGroup(btCollisionObject** bodies,int numBodies,btPersistentManifold** manifold,int numManifolds,btTypedConstraint** constraints,int numConstraints,const btContactSolverInfo& info, btIDebugDraw* debugDrawer, btStackAlloc* stackAlloc,btDispatcher* dispatcher);
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
||||
#endif //__BT_PARALLEL_CONSTRAINT_SOLVER_H
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/*
|
||||
Bullet Continuous Collision Detection and Physics Library
|
||||
Copyright (c) 2003-2007 Erwin Coumans http://bulletphysics.com
|
||||
|
||||
This software is provided 'as-is', without any express or implied warranty.
|
||||
In no event will the authors be held liable for any damages arising from the use of this software.
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it freely,
|
||||
subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
*/
|
||||
|
||||
#ifndef THREAD_SUPPORT_INTERFACE_H
|
||||
#define THREAD_SUPPORT_INTERFACE_H
|
||||
|
||||
|
||||
#include <LinearMath/btScalar.h> //for ATTRIBUTE_ALIGNED16
|
||||
#include "PlatformDefinitions.h"
|
||||
#include "PpuAddressSpace.h"
|
||||
|
||||
class btBarrier {
|
||||
public:
|
||||
btBarrier() {}
|
||||
virtual ~btBarrier() {}
|
||||
|
||||
virtual void sync() = 0;
|
||||
virtual void setMaxCount(int n) = 0;
|
||||
virtual int getMaxCount() = 0;
|
||||
};
|
||||
|
||||
class btCriticalSection {
|
||||
public:
|
||||
btCriticalSection() {}
|
||||
virtual ~btCriticalSection() {}
|
||||
|
||||
ATTRIBUTE_ALIGNED16(unsigned int mCommonBuff[32]);
|
||||
|
||||
virtual unsigned int getSharedParam(int i) = 0;
|
||||
virtual void setSharedParam(int i,unsigned int p) = 0;
|
||||
|
||||
virtual void lock() = 0;
|
||||
virtual void unlock() = 0;
|
||||
};
|
||||
|
||||
|
||||
class btThreadSupportInterface
|
||||
{
|
||||
public:
|
||||
|
||||
virtual ~btThreadSupportInterface();
|
||||
|
||||
///send messages to SPUs
|
||||
virtual void sendRequest(uint32_t uiCommand, ppu_address_t uiArgument0, uint32_t uiArgument1) =0;
|
||||
|
||||
///check for messages from SPUs
|
||||
virtual void waitForResponse(unsigned int *puiArgument0, unsigned int *puiArgument1) =0;
|
||||
|
||||
|
||||
///non-blocking test if a task is completed. First implement all versions, and then enable this API
|
||||
///virtual bool isTaskCompleted(unsigned int *puiArgument0, unsigned int *puiArgument1, int timeOutInMilliseconds)=0;
|
||||
|
||||
///start the spus (can be called at the beginning of each frame, to make sure that the right SPU program is loaded)
|
||||
virtual void startSPU() =0;
|
||||
|
||||
///tell the task scheduler we are done with the SPU tasks
|
||||
virtual void stopSPU()=0;
|
||||
|
||||
///tell the task scheduler to use no more than numTasks tasks
|
||||
virtual void setNumTasks(int numTasks)=0;
|
||||
|
||||
virtual int getNumTasks() const = 0;
|
||||
|
||||
virtual btBarrier* createBarrier() = 0;
|
||||
|
||||
virtual btCriticalSection* createCriticalSection() = 0;
|
||||
|
||||
virtual void* getThreadLocalMemory(int taskId) { return 0; }
|
||||
|
||||
};
|
||||
|
||||
#endif //THREAD_SUPPORT_INTERFACE_H
|
||||
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
Copyright (C) 2006, 2007 Sony Computer Entertainment Inc.
|
||||
All rights reserved.
|
||||
|
||||
Redistribution and use in source and binary forms,
|
||||
with or without modification, are permitted provided that the
|
||||
following conditions are met:
|
||||
* Redistributions of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
* Redistributions in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentation and/or other materials provided with the distribution.
|
||||
* Neither the name of the Sony Computer Entertainment Inc nor the names
|
||||
of its contributors may be used to endorse or promote products derived
|
||||
from this software without specific prior written permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef AOS_VECTORMATH_BULLET_CONVERT_H
|
||||
#define AOS_VECTORMATH_BULLET_CONVERT_H
|
||||
|
||||
|
||||
#include "vectormath/vmInclude.h"
|
||||
#include "LinearMath/btVector3.h"
|
||||
#include "LinearMath/btQuaternion.h"
|
||||
#include "LinearMath/btMatrix3x3.h"
|
||||
|
||||
inline Vectormath::Aos::Vector3 getVmVector3(const btVector3& bulletVec)
|
||||
{
|
||||
return Vectormath::Aos::Vector3(bulletVec.getX(),bulletVec.getY(),bulletVec.getZ());
|
||||
}
|
||||
|
||||
inline btVector3 getBtVector3(const Vectormath::Aos::Vector3& vmVec)
|
||||
{
|
||||
return btVector3(vmVec.getX(),vmVec.getY(),vmVec.getZ());
|
||||
}
|
||||
inline btVector3 getBtVector3(const Vectormath::Aos::Point3& vmVec)
|
||||
{
|
||||
return btVector3(vmVec.getX(),vmVec.getY(),vmVec.getZ());
|
||||
}
|
||||
|
||||
inline Vectormath::Aos::Quat getVmQuat(const btQuaternion& bulletQuat)
|
||||
{
|
||||
Vectormath::Aos::Quat vmQuat(bulletQuat.getX(),bulletQuat.getY(),bulletQuat.getZ(),bulletQuat.getW());
|
||||
return vmQuat;
|
||||
}
|
||||
|
||||
inline btQuaternion getBtQuat(const Vectormath::Aos::Quat& vmQuat)
|
||||
{
|
||||
return btQuaternion (vmQuat.getX(),vmQuat.getY(),vmQuat.getZ(),vmQuat.getW());
|
||||
}
|
||||
|
||||
inline Vectormath::Aos::Matrix3 getVmMatrix3(const btMatrix3x3& btMat)
|
||||
{
|
||||
Vectormath::Aos::Matrix3 mat(
|
||||
getVmVector3(btMat.getColumn(0)),
|
||||
getVmVector3(btMat.getColumn(1)),
|
||||
getVmVector3(btMat.getColumn(2)));
|
||||
return mat;
|
||||
}
|
||||
|
||||
|
||||
#endif //AOS_VECTORMATH_BULLET_CONVERT_H
|
||||
Loading…
Add table
Add a link
Reference in a new issue