@@ -51,6 +51,11 @@ __device__ inline void CUDASolveSphereCollision(const glm::vec3* sphereCenter, c
}
}

__device__ inline float CUDASign(float s)
{
return ((float)signbit(s)) * 2.0f - 1.0f;
}


__global__ void CalculateSpringsKernel(
Vertex* vertPtr,
@@ -105,12 +110,17 @@ __global__ void CalculateForcesKernel(
glm::vec3 n = glm::normalize(f);
float fLength = glm::length(f);
float spring = fLength - vertPtr[v_cur].springLengths[i];

vertPtr[v_cur].force += -vertPtr[vertPtr[v_cur].neighbours[i]].elasticity * spring * n * vertPtr[v_cur].neighbourMultipliers[i];
glm::vec3 springiness = -vertPtr[vertPtr[v_cur].neighbours[i]].elasticity * spring * n * vertPtr[v_cur].neighbourMultipliers[i];

glm::vec3 dV = vertPtr[v_cur].velocity - vertPtr[vertPtr[v_cur].neighbours[i]].velocity;
float damp = vertPtr[v_cur].elasticityDamp * (glm::dot(dV, f) / fLength);
vertPtr[v_cur].force += damp * n * vertPtr[v_cur].neighbourMultipliers[i];
float damp = vertPtr[vertPtr[v_cur].neighbours[i]].elasticityDamp * (glm::dot(dV, f) / fLength);
glm::vec3 damping = damp * n * vertPtr[v_cur].neighbourMultipliers[i];

float sL = glm::length(springiness);
float dL = glm::length(damping);
damping = (damping / glm::max(dL, 0.00000000000000001f)) * glm::min(sL, dL);

vertPtr[v_cur].force += (springiness + damping);
}


@@ -133,11 +143,12 @@ __global__ void CalculateForcesKernel(


newPos = 2.0f * posPtr[id] - vertPtr[v_cur].prevPosition + acc * delta * delta;
vertPtr[v_cur].prevPosition = posPtr[id];
posPtr[id] = newPos;

// update velocity
vertPtr[v_cur].velocity = (newPos - vertPtr[v_cur].prevPosition) / delta;

vertPtr[v_cur].prevPosition = posPtr[id];
posPtr[id] = newPos;
}

__global__ void CalculateExternalCollisionsKernel(
@@ -173,15 +184,15 @@ __global__ void CalculateExternalCollisionsKernel(
wPos.y = r.y;
wPos.z = r.z;
////////////////////

/*
float radius = 0.0f;
float divisor = 0.0f;
for (int i = 0; i < VERTEX_NEIGHBOURING_VERTICES; ++i)
{
radius += vertPtr[v_cur].springLengths[i] * vertPtr[v_cur].neighbourMultipliers[i];
divisor += vertPtr[v_cur].neighbourMultipliers[i];
}
radius = radius / divisor * vertPtr[v_cur].colliderMultiplier;
}*/
float radius = vertPtr[v_cur].colliderMultiplier;

glm::vec3 colVec;
// solve for boxes
@@ -218,6 +229,7 @@ __global__ void CalculateInternalCollisionsSpatialSubdivisionKernel(
cBoxAAData mCol = globalCol;
glm::vec3 diff = mCol.max - mCol.min;
cBoxAAData children[8];
glm::vec3 mCenter = posPtr[v_cur];
while (
diff.x > cellSize &&
diff.y > cellSize &&
@@ -265,13 +277,24 @@ __global__ void CalculateInternalCollisionsSpatialSubdivisionKernel(
/////////////

//// pick one
mCol = children[0];
for (int i = 0; i < 8; ++i)
{
if (mCenter.x >= children[i].min.x &&
mCenter.y >= children[i].min.y &&
mCenter.z >= children[i].min.z &&
mCenter.x <= children[i].max.x &&
mCenter.y <= children[i].max.y &&
mCenter.z <= children[i].max.z
)
{
mCol = children[i];
break;
}
}

diff = mCol.max - mCol.min;
}

glm::vec3 mCenter = posPtr[v_cur];


float radius = 0.0f;
float divisor = 0.0f;
@@ -372,13 +395,14 @@ __global__ void CalculateInternalCollisionsNeighboursOnlyKernel(

glm::vec3 colVec = glm::vec3(0.0f, 0.0f, 0.0f);
float radius = 0.0f;
/*
float divisor = 0.0f;
for (int i = 0; i < VERTEX_NEIGHBOURING_VERTICES; ++i)
{
radius += vertPtr[v_cur].springLengths[i] * vertPtr[v_cur].neighbourMultipliers[i];
divisor += vertPtr[v_cur].neighbourMultipliers[i];
}
radius = radius / divisor * vertPtr[v_cur].colliderMultiplier * 0.1f;
}*/
radius = vertPtr[v_cur].colliderMultiplier * 0.1f;

for (int i = 0; i < nCount; ++i)
{
@@ -483,19 +507,19 @@ unsigned int clothSpringSimulation::ClothSpringSimulationInitialize(
m_vertices[i].dampCoeff = VERTEX_AIR_DAMP;

m_vertices[i].elasticity = SPRING_ELASTICITY;
m_vertices[i].elasticityDamp = SPRING_ELASTICITY_DAMP;
m_vertices[i].colliderMultiplier = VERTEX_COLLIDER_MULTIPLIER;

if (i < m_allEdgesLength ||
i >= (m_vertexCount - m_allEdgesLength) ||
i % m_allEdgesLength == 0 ||
i % m_allEdgesLength == (m_allEdgesLength - 1)
)
{
m_vertices[i].elasticity *= SPRING_BORDER_MULTIPLIER;
//m_vertices[i].elasticityDamp *= SPRING_BORDER_MULTIPLIER;
}


m_vertices[i].elasticityDamp = SPRING_ELASTICITY_DAMP;
m_vertices[i].colliderMultiplier = VERTEX_COLLIDER_MULTIPLIER;

// calculating neighbouring vertices ids and spring lengths

// upper
@@ -726,7 +750,7 @@ unsigned int clothSpringSimulation::ClothSpringSimulationUpdate(float gravity, d
}
printf("\n");
*/
//printf("%f %f %f \n", m_nrmPtr[0].x, m_nrmPtr[0].y, m_nrmPtr[0].z);
//printf("%f %f %f \n", m_vertices[59].velocity.x, m_vertices[59].velocity.y, m_vertices[59].velocity.z);


return CS_ERR_NONE;
@@ -811,7 +835,7 @@ inline cudaError_t clothSpringSimulation::CalculateForces(float gravity, double
return status;
}

status = cudaMemcpy(i_scldPtr, boxColliders, m_sphereColliderCount * sizeof(SphereCollider), cudaMemcpyHostToDevice);
status = cudaMemcpy(i_scldPtr, sphereColliders, m_sphereColliderCount * sizeof(SphereCollider), cudaMemcpyHostToDevice);
if (status != cudaSuccess) {
fprintf(stderr, "cudaMemcpy failed!");
FreeMemory();
@@ -837,10 +861,11 @@ inline cudaError_t clothSpringSimulation::CalculateForces(float gravity, double
dim3 blockVerts(p, p, 1);
//dim3 blockSprings(p, p, 1);

double nDelta = delta / 25000.0;

for (int i = 1; i <= steps; ++i)
{
CalculateForcesKernel << < gridVerts, blockVerts >> > (i_vertexPtr, i_posPtr, i_nrmPtr, i_colPtr, gravity, FIXED_DELTA / steps, m_vertexCount);
CalculateForcesKernel << < gridVerts, blockVerts >> > (i_vertexPtr, i_posPtr, i_nrmPtr, i_colPtr, gravity, nDelta / steps, m_vertexCount);
CalculateExternalCollisionsKernel << < gridVerts, blockVerts >> > (i_vertexPtr, i_posPtr, i_bcldPtr, i_scldPtr,
i_wmPtr, m_boxColliderCount, m_sphereColliderCount, m_vertexCount);
//CalculateInternalCollisionsSimpleKernel << < gridVerts, blockVerts >> > (i_vertexPtr, i_posPtr, m_vertexCount);
@@ -86,11 +86,11 @@ class clothSpringSimulation

cudaDeviceProp* m_deviceProperties;

const float VERTEX_MASS = 0.001f;
const float VERTEX_AIR_DAMP = 0.0001f;
const float SPRING_ELASTICITY = 0.5f;
const float VERTEX_MASS = 1.0f;
const float VERTEX_AIR_DAMP = 0.01f;
const float SPRING_ELASTICITY = 50.00f;
const float SPRING_BORDER_MULTIPLIER = 50.0f;
const float SPRING_ELASTICITY_DAMP = 0.000005f;
const float SPRING_ELASTICITY_DAMP = -100.25f;
const float VERTEX_COLLIDER_MULTIPLIER = 0.5f;
const float CELL_OFFSET = 0.01f;