~ubuntu-branches/ubuntu/vivid/emscripten/vivid

« back to all changes in this revision

Viewing changes to tests/bullet/src/BulletMultiThreaded/GpuSoftBodySolvers/OpenCL/OpenCLC/SolveCollisionsAndUpdateVelocities.cl

  • Committer: Package Import Robot
  • Author(s): Sylvestre Ledru
  • Date: 2013-05-02 13:11:51 UTC
  • Revision ID: package-import@ubuntu.com-20130502131151-q8dvteqr1ef2x7xz
Tags: upstream-1.4.1~20130504~adb56cb
ImportĀ upstreamĀ versionĀ 1.4.1~20130504~adb56cb

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
MSTRINGIFY(
 
2
 
 
3
typedef struct 
 
4
{
 
5
        int firstObject;
 
6
        int endObject;
 
7
} CollisionObjectIndices;
 
8
 
 
9
typedef struct 
 
10
{
 
11
        float4 shapeTransform[4]; // column major 4x4 matrix
 
12
        float4 linearVelocity;
 
13
        float4 angularVelocity;
 
14
 
 
15
        int softBodyIdentifier;
 
16
        int collisionShapeType;
 
17
        
 
18
 
 
19
        // Shape information
 
20
        // Compressed from the union
 
21
        float radius;
 
22
        float halfHeight;
 
23
        int upAxis;
 
24
                
 
25
        float margin;
 
26
        float friction;
 
27
 
 
28
        int padding0;
 
29
        
 
30
} CollisionShapeDescription;
 
31
 
 
32
/* From btBroadphaseProxy.h */
 
33
__constant int CAPSULE_SHAPE_PROXYTYPE = 10;
 
34
 
 
35
/* Multiply column-major matrix against vector */
 
36
float4 matrixVectorMul( float4 matrix[4], float4 vector )
 
37
{
 
38
        float4 returnVector;
 
39
        float4 row0 = (float4)(matrix[0].x, matrix[1].x, matrix[2].x, matrix[3].x);
 
40
        float4 row1 = (float4)(matrix[0].y, matrix[1].y, matrix[2].y, matrix[3].y);
 
41
        float4 row2 = (float4)(matrix[0].z, matrix[1].z, matrix[2].z, matrix[3].z);
 
42
        float4 row3 = (float4)(matrix[0].w, matrix[1].w, matrix[2].w, matrix[3].w);
 
43
        returnVector.x = dot(row0, vector);
 
44
        returnVector.y = dot(row1, vector);
 
45
        returnVector.z = dot(row2, vector);
 
46
        returnVector.w = dot(row3, vector);
 
47
        return returnVector;
 
48
}
 
49
 
 
50
__kernel void 
 
51
SolveCollisionsAndUpdateVelocitiesKernel( 
 
52
        const int numNodes,
 
53
        const float isolverdt,
 
54
        __global int *g_vertexClothIdentifier,
 
55
        __global float4 *g_vertexPreviousPositions,
 
56
        __global float * g_perClothFriction,
 
57
        __global float * g_clothDampingFactor,
 
58
        __global CollisionObjectIndices * g_perClothCollisionObjectIndices,
 
59
        __global CollisionShapeDescription * g_collisionObjectDetails,
 
60
        __global float4 * g_vertexForces,
 
61
        __global float4 *g_vertexVelocities,
 
62
        __global float4 *g_vertexPositions)
 
63
{
 
64
        int nodeID = get_global_id(0);
 
65
        float3 forceOnVertex = (float3)(0.f, 0.f, 0.f);
 
66
        if( get_global_id(0) < numNodes )
 
67
        {       
 
68
                int clothIdentifier = g_vertexClothIdentifier[nodeID];
 
69
                
 
70
                // Abort if this is not a valid cloth
 
71
                if( clothIdentifier < 0 )
 
72
                        return;
 
73
 
 
74
                float4 position = (float4)(g_vertexPositions[nodeID].xyz, 1.f);
 
75
                float4 previousPosition = (float4)(g_vertexPreviousPositions[nodeID].xyz, 1.f);
 
76
                float3 velocity;
 
77
                float clothFriction = g_perClothFriction[clothIdentifier];
 
78
                float dampingFactor = g_clothDampingFactor[clothIdentifier];
 
79
                float velocityCoefficient = (1.f - dampingFactor);              
 
80
                CollisionObjectIndices collisionObjectIndices = g_perClothCollisionObjectIndices[clothIdentifier];
 
81
        
 
82
                if( collisionObjectIndices.firstObject != collisionObjectIndices.endObject )
 
83
                {
 
84
                        velocity = (float3)(15, 0, 0);
 
85
 
 
86
                        /* We have some possible collisions to deal with */
 
87
                        for( int collision = collisionObjectIndices.firstObject; collision < collisionObjectIndices.endObject; ++collision )
 
88
                        {
 
89
                                CollisionShapeDescription shapeDescription = g_collisionObjectDetails[collision];
 
90
                                float colliderFriction = shapeDescription.friction;
 
91
                
 
92
                                if( shapeDescription.collisionShapeType == CAPSULE_SHAPE_PROXYTYPE )
 
93
                                {
 
94
                                        /* Colliding with a capsule */
 
95
 
 
96
                                        float capsuleHalfHeight = shapeDescription.halfHeight;
 
97
                                        float capsuleRadius = shapeDescription.radius;
 
98
                                        float capsuleMargin = shapeDescription.margin;
 
99
                                        int capsuleupAxis = shapeDescription.upAxis;
 
100
 
 
101
                                        /* Four columns of worldTransform matrix */
 
102
                                        float4 worldTransform[4];
 
103
                                        worldTransform[0] = shapeDescription.shapeTransform[0];
 
104
                                        worldTransform[1] = shapeDescription.shapeTransform[1];
 
105
                                        worldTransform[2] = shapeDescription.shapeTransform[2];
 
106
                                        worldTransform[3] = shapeDescription.shapeTransform[3];
 
107
 
 
108
                                        // Correctly define capsule centerline vector 
 
109
                                        float4 c1 = (float4)(0.f, 0.f, 0.f, 1.f); 
 
110
                                        float4 c2 = (float4)(0.f, 0.f, 0.f, 1.f);
 
111
                                        c1.x = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 0 );
 
112
                                        c1.y = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 1 );
 
113
                                        c1.z = select( 0.f, -capsuleHalfHeight, capsuleupAxis == 2 );
 
114
                                        c2.x = -c1.x;
 
115
                                        c2.y = -c1.y;
 
116
                                        c2.z = -c1.z;
 
117
 
 
118
                                        float4 worldC1 = matrixVectorMul(worldTransform, c1);
 
119
                                        float4 worldC2 = matrixVectorMul(worldTransform, c2);
 
120
                                        float3 segment = (worldC2 - worldC1).xyz;
 
121
 
 
122
                                        /* compute distance of tangent to vertex along line segment in capsule */
 
123
                                        float distanceAlongSegment = -( dot( (worldC1 - position).xyz, segment ) / dot(segment, segment) );
 
124
 
 
125
                                        float4 closestPoint = (worldC1 + (float4)(segment * distanceAlongSegment, 0.f));
 
126
                                        float distanceFromLine = length(position - closestPoint);
 
127
                                        float distanceFromC1 = length(worldC1 - position);
 
128
                                        float distanceFromC2 = length(worldC2 - position);
 
129
                                        
 
130
                                        /* Final distance from collision, point to push from, direction to push in
 
131
                                           for impulse force */
 
132
                                        float dist;
 
133
                                        float3 normalVector;
 
134
                                        if( distanceAlongSegment < 0 )
 
135
                                        {
 
136
                                                dist = distanceFromC1;
 
137
                                                normalVector = normalize(position - worldC1).xyz;
 
138
                                        } else if( distanceAlongSegment > 1.f ) {
 
139
                                                dist = distanceFromC2;
 
140
                                                normalVector = normalize(position - worldC2).xyz;       
 
141
                                        } else {
 
142
                                                dist = distanceFromLine;
 
143
                                                normalVector = normalize(position - closestPoint).xyz;
 
144
                                        }
 
145
                                                
 
146
                                        float3 colliderLinearVelocity = shapeDescription.linearVelocity.xyz;
 
147
                                        float3 colliderAngularVelocity = shapeDescription.angularVelocity.xyz;
 
148
                                        float3 velocityOfSurfacePoint = colliderLinearVelocity + cross(colliderAngularVelocity, position.xyz - (float3)(worldTransform[0].w, worldTransform[1].w, worldTransform[2].w));
 
149
 
 
150
                                        float minDistance = capsuleRadius + capsuleMargin;
 
151
                                        
 
152
                                        /* In case of no collision, this is the value of velocity */
 
153
                                        velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
 
154
                                        
 
155
                                        
 
156
                                        // Check for a collision
 
157
                                        if( dist < minDistance )
 
158
                                        {
 
159
                                                /* Project back to surface along normal */
 
160
                                                position = position + (float4)((minDistance - dist)*normalVector*0.9f, 0.f);
 
161
                                                velocity = (position - previousPosition).xyz * velocityCoefficient * isolverdt;
 
162
                                                float3 relativeVelocity = velocity - velocityOfSurfacePoint;
 
163
 
 
164
                                                float3 p1 = normalize(cross(normalVector, segment));
 
165
                                                float3 p2 = normalize(cross(p1, normalVector));
 
166
                                                /* Full friction is sum of velocities in each direction of plane */
 
167
                                                float3 frictionVector = p1*dot(relativeVelocity, p1) + p2*dot(relativeVelocity, p2);
 
168
 
 
169
                                                /* Real friction is peak friction corrected by friction coefficients */
 
170
                                                frictionVector = frictionVector * (colliderFriction*clothFriction);
 
171
 
 
172
                                                float approachSpeed = dot(relativeVelocity, normalVector);
 
173
 
 
174
                                                if( approachSpeed <= 0.0f )
 
175
                                                        forceOnVertex -= frictionVector;
 
176
                                        }
 
177
                                        
 
178
                                }
 
179
                        }
 
180
                } else {
 
181
                        /* Update velocity       */
 
182
                        float3 difference = position.xyz - previousPosition.xyz;
 
183
                        velocity = difference*velocityCoefficient*isolverdt;                    
 
184
                }
 
185
 
 
186
                g_vertexVelocities[nodeID] = (float4)(velocity, 0.f);   
 
187
 
 
188
                /* Update external force */
 
189
                g_vertexForces[nodeID] = (float4)(forceOnVertex, 0.f);
 
190
 
 
191
                g_vertexPositions[nodeID] = (float4)(position.xyz, 0.f);
 
192
        }
 
193
}
 
194
 
 
195
);