00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <MiniCL/cl_MiniCL_Defs.h>
00017
00018 #define MSTRINGIFY(A) A
00019 #include "../OpenCLC10/ApplyForces.cl"
00020 #include "../OpenCLC10/Integrate.cl"
00021 #include "../OpenCLC10/PrepareLinks.cl"
00022 #include "../OpenCLC10/SolvePositions.cl"
00023 #include "../OpenCLC10/UpdateNodes.cl"
00024 #include "../OpenCLC10/UpdateNormals.cl"
00025 #include "../OpenCLC10/UpdatePositions.cl"
00026 #include "../OpenCLC10/UpdatePositionsFromVelocities.cl"
00027 #include "../OpenCLC10/VSolveLinks.cl"
00028 #include "../OpenCLC10/UpdateFixedVertexPositions.cl"
00029
00030
00031
00032 MINICL_REGISTER(PrepareLinksKernel)
00033 MINICL_REGISTER(VSolveLinksKernel)
00034 MINICL_REGISTER(UpdatePositionsFromVelocitiesKernel)
00035 MINICL_REGISTER(SolvePositionsFromLinksKernel)
00036 MINICL_REGISTER(updateVelocitiesFromPositionsWithVelocitiesKernel)
00037 MINICL_REGISTER(updateVelocitiesFromPositionsWithoutVelocitiesKernel)
00038 MINICL_REGISTER(IntegrateKernel)
00039 MINICL_REGISTER(ApplyForcesKernel)
00040 MINICL_REGISTER(ResetNormalsAndAreasKernel)
00041 MINICL_REGISTER(NormalizeNormalsAndAreasKernel)
00042 MINICL_REGISTER(UpdateSoftBodiesKernel)
00043 MINICL_REGISTER(UpdateFixedVertexPositions)
00044
00045 float mydot3a(float4 a, float4 b)
00046 {
00047 return a.x*b.x + a.y*b.y + a.z*b.z;
00048 }
00049
00050
00051 typedef struct
00052 {
00053 int firstObject;
00054 int endObject;
00055 } CollisionObjectIndices;
00056
00057 typedef struct
00058 {
00059 float4 shapeTransform[4];
00060 float4 linearVelocity;
00061 float4 angularVelocity;
00062
00063 int softBodyIdentifier;
00064 int collisionShapeType;
00065
00066
00067
00068
00069 float radius;
00070 float halfHeight;
00071 int upAxis;
00072
00073 float margin;
00074 float friction;
00075
00076 int padding0;
00077
00078 } CollisionShapeDescription;
00079
00080
00081 __constant int CAPSULE_SHAPE_PROXYTYPE = 10;
00082
00083
00084 float4 matrixVectorMul( float4 matrix[4], float4 vector )
00085 {
00086 float4 returnVector;
00087 float4 row0 = float4(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x);
00088 float4 row1 = float4(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y);
00089 float4 row2 = float4(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z);
00090 float4 row3 = float4(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w);
00091 returnVector.x = dot(row0, vector);
00092 returnVector.y = dot(row1, vector);
00093 returnVector.z = dot(row2, vector);
00094 returnVector.w = dot(row3, vector);
00095 return returnVector;
00096 }
00097
00098 __kernel void
00099 SolveCollisionsAndUpdateVelocitiesKernel(
00100 const int numNodes,
00101 const float isolverdt,
00102 __global int *g_vertexClothIdentifier,
00103 __global float4 *g_vertexPreviousPositions,
00104 __global float * g_perClothFriction,
00105 __global float * g_clothDampingFactor,
00106 __global CollisionObjectIndices * g_perClothCollisionObjectIndices,
00107 __global CollisionShapeDescription * g_collisionObjectDetails,
00108 __global float4 * g_vertexForces,
00109 __global float4 *g_vertexVelocities,
00110 __global float4 *g_vertexPositions GUID_ARG)
00111 {
00112 int nodeID = get_global_id(0);
00113 float4 forceOnVertex = (float4)(0.f, 0.f, 0.f, 0.f);
00114
00115 if( get_global_id(0) < numNodes )
00116 {
00117 int clothIdentifier = g_vertexClothIdentifier[nodeID];
00118
00119
00120 if( clothIdentifier < 0 )
00121 return;
00122
00123
00124 float4 position (g_vertexPositions[nodeID].xyz, 1.f);
00125 float4 previousPosition (g_vertexPreviousPositions[nodeID].xyz, 1.f);
00126
00127 float clothFriction = g_perClothFriction[clothIdentifier];
00128 float dampingFactor = g_clothDampingFactor[clothIdentifier];
00129 float velocityCoefficient = (1.f - dampingFactor);
00130 float4 difference = position - previousPosition;
00131 float4 velocity = difference*velocityCoefficient*isolverdt;
00132
00133 CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
00134
00135 int numObjects = collisionObjectIndices.endObject - collisionObjectIndices.firstObject;
00136
00137 if( numObjects > 0 )
00138 {
00139
00140 for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision )
00141 {
00142 CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision];
00143 float colliderFriction = shapeDescription.friction;
00144
00145 if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
00146 {
00147
00148
00149 float capsuleHalfHeight = shapeDescription.halfHeight;
00150 float capsuleRadius = shapeDescription.radius;
00151 float capsuleMargin = shapeDescription.margin;
00152 int capsuleupAxis = shapeDescription.upAxis;
00153
00154
00155 float4 worldTransform[4];
00156 worldTransform[0] = shapeDescription.shapeTransform[0];
00157 worldTransform[1] = shapeDescription.shapeTransform[1];
00158 worldTransform[2] = shapeDescription.shapeTransform[2];
00159 worldTransform[3] = shapeDescription.shapeTransform[3];
00160
00161
00162 float4 c1 (0.f, 0.f, 0.f, 1.f);
00163 float4 c2 (0.f, 0.f, 0.f, 1.f);
00164 c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 );
00165 c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 );
00166 c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 );
00167 c2.x = -c1.x;
00168 c2.y = -c1.y;
00169 c2.z = -c1.z;
00170
00171
00172 float4 worldC1 = matrixVectorMul(worldTransform, c1);
00173 float4 worldC2 = matrixVectorMul(worldTransform, c2);
00174 float4 segment = (worldC2 - worldC1);
00175
00176
00177 float distanceAlongSegment = -( mydot3a( (worldC1 - position), segment ) / mydot3a(segment, segment) );
00178
00179 float4 closestPoint = (worldC1 + (segment * distanceAlongSegment));
00180 float distanceFromLine = length(position - closestPoint);
00181 float distanceFromC1 = length(worldC1 - position);
00182 float distanceFromC2 = length(worldC2 - position);
00183
00184
00185
00186 float dist;
00187 float4 normalVector;
00188 if( distanceAlongSegment < 0 )
00189 {
00190 dist = distanceFromC1;
00191 normalVector = float4(normalize(position - worldC1).xyz, 0.f);
00192 } else if( distanceAlongSegment > 1.f ) {
00193 dist = distanceFromC2;
00194 normalVector = float4(normalize(position - worldC2).xyz, 0.f);
00195 } else {
00196 dist = distanceFromLine;
00197 normalVector = float4(normalize(position - closestPoint).xyz, 0.f);
00198 }
00199
00200 float4 colliderLinearVelocity = shapeDescription.linearVelocity;
00201 float4 colliderAngularVelocity = shapeDescription.angularVelocity;
00202 float4 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position - float4(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w, 0.f));
00203
00204 float minDistance = capsuleRadius + capsuleMargin;
00205
00206
00207 velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
00208
00209
00210
00211 if( dist < minDistance )
00212 {
00213
00214 position = position + float4(normalVector*(minDistance - dist)*0.9f);
00215 velocity = (position - previousPosition) * velocityCoefficient * isolverdt;
00216 float4 relativeVelocity = velocity - velocityOfSurfacePoint;
00217
00218 float4 p1 = normalize(cross(normalVector, segment));
00219 float4 p2 = normalize(cross(p1, normalVector));
00220
00221 float4 frictionVector = p1*mydot3a(relativeVelocity, p1) + p2*mydot3a(relativeVelocity, p2);
00222
00223
00224 frictionVector = frictionVector * (colliderFriction*clothFriction);
00225
00226 float approachSpeed = dot(relativeVelocity, normalVector);
00227
00228 if( approachSpeed <= 0.0f )
00229 forceOnVertex -= frictionVector;
00230 }
00231 }
00232 }
00233 }
00234
00235 g_vertexVelocities[nodeID] = float4(velocity.xyz, 0.f);
00236
00237
00238 g_vertexForces[nodeID] = float4(forceOnVertex.xyz, 0.f);
00239
00240 g_vertexPositions[nodeID] = float4(position.xyz, 0.f);
00241 }
00242 }
00243
00244
00245 MINICL_REGISTER(SolveCollisionsAndUpdateVelocitiesKernel);
00246
00247
00248
00249