This commit is contained in:
ejcoumans 2007-06-13 05:00:42 +00:00
parent 705e6df404
commit ee8322ae6b
273 changed files with 23899 additions and 1359 deletions

View File

@ -18,4 +18,5 @@ Joerg Henrichs: make buildsystem (work in progress)
Eric Sunshine: jam + msvcgen buildsystem
Steve Baker: GPU physics and general implementation improvements
Jay Lee: Double precision support
KleMiX, aka Vsevolod Klementjev, managed version, rewritten in C# for XNA
Erwin Coumans: most other source code

View File

@ -8,6 +8,7 @@ Erwin Coumans
- Added managed Bullet library, entirely rewritten in C# for Windows and XBox 360 XNA
See Extras/BulletX
Thanks to KleMiX, aka Vsevolod Klementjev
2007 May 31
- sign-bit went wrong in case of 32-bit broadphase, causing quantization problems.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1,228 @@
xof 0303txt 0032
template Frame {
<3d82ab46-62da-11cf-ab39-0020af71e433>
[...]
}
template Matrix4x4 {
<f6f23f45-7686-11cf-8f52-0040333594a3>
array FLOAT matrix[16];
}
template FrameTransformMatrix {
<f6f23f41-7686-11cf-8f52-0040333594a3>
Matrix4x4 frameMatrix;
}
template Vector {
<3d82ab5e-62da-11cf-ab39-0020af71e433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template MeshFace {
<3d82ab5f-62da-11cf-ab39-0020af71e433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template Mesh {
<3d82ab44-62da-11cf-ab39-0020af71e433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template MeshNormals {
<f6f23f43-7686-11cf-8f52-0040333594a3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template ColorRGBA {
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<d3e16e81-7835-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template Material {
<3d82ab4d-62da-11cf-ab39-0020af71e433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshMaterialList {
<f6f23f42-7686-11cf-8f52-0040333594a3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
}
template VertexDuplicationIndices {
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
DWORD nIndices;
DWORD nOriginalVertices;
array DWORD indices[nIndices];
}
Frame {
FrameTransformMatrix {
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
}
Mesh {
24;
-0.500000;-0.500000;-0.500000;,
-0.500000;-0.500000;0.500000;,
-0.500000;0.500000;0.500000;,
-0.500000;0.500000;-0.500000;,
-0.500000;0.500000;-0.500000;,
-0.500000;0.500000;0.500000;,
0.500000;0.500000;0.500000;,
0.500000;0.500000;-0.500000;,
0.500000;0.500000;-0.500000;,
0.500000;0.500000;0.500000;,
0.500000;-0.500000;0.500000;,
0.500000;-0.500000;-0.500000;,
-0.500000;-0.500000;0.500000;,
-0.500000;-0.500000;-0.500000;,
0.500000;-0.500000;-0.500000;,
0.500000;-0.500000;0.500000;,
-0.500000;-0.500000;0.500000;,
0.500000;-0.500000;0.500000;,
0.500000;0.500000;0.500000;,
-0.500000;0.500000;0.500000;,
-0.500000;-0.500000;-0.500000;,
-0.500000;0.500000;-0.500000;,
0.500000;0.500000;-0.500000;,
0.500000;-0.500000;-0.500000;;
12;
3;0,1,2;,
3;2,3,0;,
3;4,5,6;,
3;6,7,4;,
3;8,9,10;,
3;10,11,8;,
3;12,13,14;,
3;14,15,12;,
3;16,17,18;,
3;18,19,16;,
3;20,21,22;,
3;22,23,20;;
MeshNormals {
24;
-1.000000;0.000000;0.000000;,
-1.000000;0.000000;0.000000;,
-1.000000;0.000000;0.000000;,
-1.000000;0.000000;0.000000;,
0.000000;1.000000;0.000000;,
0.000000;1.000000;0.000000;,
0.000000;1.000000;0.000000;,
0.000000;1.000000;0.000000;,
1.000000;0.000000;0.000000;,
1.000000;0.000000;0.000000;,
1.000000;0.000000;0.000000;,
1.000000;0.000000;0.000000;,
0.000000;-1.000000;0.000000;,
0.000000;-1.000000;0.000000;,
0.000000;-1.000000;0.000000;,
0.000000;-1.000000;0.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;;
12;
3;0,1,2;,
3;2,3,0;,
3;4,5,6;,
3;6,7,4;,
3;8,9,10;,
3;10,11,8;,
3;12,13,14;,
3;14,15,12;,
3;16,17,18;,
3;18,19,16;,
3;20,21,22;,
3;22,23,20;;
}
MeshMaterialList {
1;
12;
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0;
Material {
0.500000;0.500000;0.500000;0.000000;;
0.000000;
0.500000;0.500000;0.500000;;
0.000000;0.000000;0.000000;;
}
}
VertexDuplicationIndices {
24;
8;
0,
1,
2,
3,
3,
2,
6,
7,
7,
6,
10,
11,
1,
0,
11,
10,
1,
10,
6,
2,
0,
3,
7,
11;
}
}
}

View File

@ -0,0 +1,786 @@
xof 0303txt 0032
template Frame {
<3d82ab46-62da-11cf-ab39-0020af71e433>
[...]
}
template Matrix4x4 {
<f6f23f45-7686-11cf-8f52-0040333594a3>
array FLOAT matrix[16];
}
template FrameTransformMatrix {
<f6f23f41-7686-11cf-8f52-0040333594a3>
Matrix4x4 frameMatrix;
}
template Vector {
<3d82ab5e-62da-11cf-ab39-0020af71e433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template MeshFace {
<3d82ab5f-62da-11cf-ab39-0020af71e433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template Mesh {
<3d82ab44-62da-11cf-ab39-0020af71e433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template MeshNormals {
<f6f23f43-7686-11cf-8f52-0040333594a3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template ColorRGBA {
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<d3e16e81-7835-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template Material {
<3d82ab4d-62da-11cf-ab39-0020af71e433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshMaterialList {
<f6f23f42-7686-11cf-8f52-0040333594a3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
}
template VertexDuplicationIndices {
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
DWORD nIndices;
DWORD nOriginalVertices;
array DWORD indices[nIndices];
}
Frame {
FrameTransformMatrix {
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
}
Mesh {
102;
0.000000;0.000000;-1.500000;,
0.000000;1.000000;-1.500000;,
0.309017;0.951057;-1.500000;,
0.587785;0.809017;-1.500000;,
0.809017;0.587785;-1.500000;,
0.951057;0.309017;-1.500000;,
1.000000;-0.000000;-1.500000;,
0.951057;-0.309017;-1.500000;,
0.809017;-0.587785;-1.500000;,
0.587785;-0.809017;-1.500000;,
0.309017;-0.951057;-1.500000;,
-0.000000;-1.000000;-1.500000;,
-0.309017;-0.951056;-1.500000;,
-0.587785;-0.809017;-1.500000;,
-0.809017;-0.587785;-1.500000;,
-0.951057;-0.309017;-1.500000;,
-1.000000;0.000000;-1.500000;,
-0.951057;0.309017;-1.500000;,
-0.809017;0.587786;-1.500000;,
-0.587785;0.809017;-1.500000;,
-0.309017;0.951057;-1.500000;,
0.000000;1.000000;-1.500000;,
0.309017;0.951057;-1.500000;,
0.587785;0.809017;-1.500000;,
0.809017;0.587785;-1.500000;,
0.951057;0.309017;-1.500000;,
1.000000;-0.000000;-1.500000;,
0.951057;-0.309017;-1.500000;,
0.809017;-0.587785;-1.500000;,
0.587785;-0.809017;-1.500000;,
0.309017;-0.951057;-1.500000;,
-0.000000;-1.000000;-1.500000;,
-0.309017;-0.951056;-1.500000;,
-0.587785;-0.809017;-1.500000;,
-0.809017;-0.587785;-1.500000;,
-0.951057;-0.309017;-1.500000;,
-1.000000;0.000000;-1.500000;,
-0.951057;0.309017;-1.500000;,
-0.809017;0.587786;-1.500000;,
-0.587785;0.809017;-1.500000;,
-0.309017;0.951057;-1.500000;,
0.000000;1.000000;0.000000;,
0.309017;0.951057;0.000000;,
0.587785;0.809017;0.000000;,
0.809017;0.587785;0.000000;,
0.951057;0.309017;0.000000;,
1.000000;-0.000000;0.000000;,
0.951057;-0.309017;0.000000;,
0.809017;-0.587785;0.000000;,
0.587785;-0.809017;0.000000;,
0.309017;-0.951057;0.000000;,
-0.000000;-1.000000;0.000000;,
-0.309017;-0.951056;0.000000;,
-0.587785;-0.809017;0.000000;,
-0.809017;-0.587785;0.000000;,
-0.951057;-0.309017;0.000000;,
-1.000000;0.000000;0.000000;,
-0.951057;0.309017;0.000000;,
-0.809017;0.587786;0.000000;,
-0.587785;0.809017;0.000000;,
-0.309017;0.951057;0.000000;,
0.000000;1.000000;1.500000;,
0.309017;0.951057;1.500000;,
0.587785;0.809017;1.500000;,
0.809017;0.587785;1.500000;,
0.951057;0.309017;1.500000;,
1.000000;-0.000000;1.500000;,
0.951057;-0.309017;1.500000;,
0.809017;-0.587785;1.500000;,
0.587785;-0.809017;1.500000;,
0.309017;-0.951057;1.500000;,
-0.000000;-1.000000;1.500000;,
-0.309017;-0.951056;1.500000;,
-0.587785;-0.809017;1.500000;,
-0.809017;-0.587785;1.500000;,
-0.951057;-0.309017;1.500000;,
-1.000000;0.000000;1.500000;,
-0.951057;0.309017;1.500000;,
-0.809017;0.587786;1.500000;,
-0.587785;0.809017;1.500000;,
-0.309017;0.951057;1.500000;,
0.000000;1.000000;1.500000;,
0.309017;0.951057;1.500000;,
0.587785;0.809017;1.500000;,
0.809017;0.587785;1.500000;,
0.951057;0.309017;1.500000;,
1.000000;-0.000000;1.500000;,
0.951057;-0.309017;1.500000;,
0.809017;-0.587785;1.500000;,
0.587785;-0.809017;1.500000;,
0.309017;-0.951057;1.500000;,
-0.000000;-1.000000;1.500000;,
-0.309017;-0.951056;1.500000;,
-0.587785;-0.809017;1.500000;,
-0.809017;-0.587785;1.500000;,
-0.951057;-0.309017;1.500000;,
-1.000000;0.000000;1.500000;,
-0.951057;0.309017;1.500000;,
-0.809017;0.587786;1.500000;,
-0.587785;0.809017;1.500000;,
-0.309017;0.951057;1.500000;,
0.000000;0.000000;1.500000;;
120;
3;0,1,2;,
3;0,2,3;,
3;0,3,4;,
3;0,4,5;,
3;0,5,6;,
3;0,6,7;,
3;0,7,8;,
3;0,8,9;,
3;0,9,10;,
3;0,10,11;,
3;0,11,12;,
3;0,12,13;,
3;0,13,14;,
3;0,14,15;,
3;0,15,16;,
3;0,16,17;,
3;0,17,18;,
3;0,18,19;,
3;0,19,20;,
3;0,20,1;,
3;21,41,22;,
3;22,41,42;,
3;22,42,23;,
3;23,42,43;,
3;23,43,24;,
3;24,43,44;,
3;24,44,25;,
3;25,44,45;,
3;25,45,26;,
3;26,45,46;,
3;26,46,27;,
3;27,46,47;,
3;27,47,28;,
3;28,47,48;,
3;28,48,29;,
3;29,48,49;,
3;29,49,30;,
3;30,49,50;,
3;30,50,31;,
3;31,50,51;,
3;31,51,32;,
3;32,51,52;,
3;32,52,33;,
3;33,52,53;,
3;33,53,34;,
3;34,53,54;,
3;34,54,35;,
3;35,54,55;,
3;35,55,36;,
3;36,55,56;,
3;36,56,37;,
3;37,56,57;,
3;37,57,38;,
3;38,57,58;,
3;38,58,39;,
3;39,58,59;,
3;39,59,40;,
3;40,59,60;,
3;40,60,21;,
3;21,60,41;,
3;41,61,42;,
3;42,61,62;,
3;42,62,43;,
3;43,62,63;,
3;43,63,44;,
3;44,63,64;,
3;44,64,45;,
3;45,64,65;,
3;45,65,46;,
3;46,65,66;,
3;46,66,47;,
3;47,66,67;,
3;47,67,48;,
3;48,67,68;,
3;48,68,49;,
3;49,68,69;,
3;49,69,50;,
3;50,69,70;,
3;50,70,51;,
3;51,70,71;,
3;51,71,52;,
3;52,71,72;,
3;52,72,53;,
3;53,72,73;,
3;53,73,54;,
3;54,73,74;,
3;54,74,55;,
3;55,74,75;,
3;55,75,56;,
3;56,75,76;,
3;56,76,57;,
3;57,76,77;,
3;57,77,58;,
3;58,77,78;,
3;58,78,59;,
3;59,78,79;,
3;59,79,60;,
3;60,79,80;,
3;60,80,41;,
3;41,80,61;,
3;81,101,82;,
3;82,101,83;,
3;83,101,84;,
3;84,101,85;,
3;85,101,86;,
3;86,101,87;,
3;87,101,88;,
3;88,101,89;,
3;89,101,90;,
3;90,101,91;,
3;91,101,92;,
3;92,101,93;,
3;93,101,94;,
3;94,101,95;,
3;95,101,96;,
3;96,101,97;,
3;97,101,98;,
3;98,101,99;,
3;99,101,100;,
3;100,101,81;;
MeshNormals {
102;
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;0.000000;-1.000000;,
0.000000;1.000000;0.000000;,
0.309017;0.951057;0.000000;,
0.587785;0.809017;0.000000;,
0.809017;0.587785;0.000000;,
0.951057;0.309017;0.000000;,
1.000000;-0.000000;0.000000;,
0.951057;-0.309017;0.000000;,
0.809017;-0.587785;0.000000;,
0.587785;-0.809017;0.000000;,
0.309017;-0.951057;0.000000;,
-0.000000;-1.000000;0.000000;,
-0.309017;-0.951056;0.000000;,
-0.587785;-0.809017;0.000000;,
-0.809017;-0.587785;0.000000;,
-0.951057;-0.309017;0.000000;,
-1.000000;0.000000;0.000000;,
-0.951057;0.309017;0.000000;,
-0.809017;0.587786;0.000000;,
-0.587785;0.809017;0.000000;,
-0.309017;0.951057;0.000000;,
0.000000;1.000000;0.000000;,
0.309017;0.951057;0.000000;,
0.587785;0.809017;0.000000;,
0.809017;0.587785;0.000000;,
0.951057;0.309017;0.000000;,
1.000000;-0.000000;0.000000;,
0.951057;-0.309017;0.000000;,
0.809017;-0.587785;0.000000;,
0.587785;-0.809017;0.000000;,
0.309017;-0.951057;0.000000;,
-0.000000;-1.000000;0.000000;,
-0.309017;-0.951056;0.000000;,
-0.587785;-0.809017;0.000000;,
-0.809017;-0.587785;0.000000;,
-0.951057;-0.309017;0.000000;,
-1.000000;0.000000;0.000000;,
-0.951057;0.309017;0.000000;,
-0.809017;0.587786;0.000000;,
-0.587785;0.809017;0.000000;,
-0.309017;0.951057;0.000000;,
0.000000;1.000000;0.000000;,
0.309017;0.951057;0.000000;,
0.587785;0.809017;0.000000;,
0.809017;0.587785;0.000000;,
0.951057;0.309017;0.000000;,
1.000000;-0.000000;0.000000;,
0.951057;-0.309017;0.000000;,
0.809017;-0.587785;0.000000;,
0.587785;-0.809017;0.000000;,
0.309017;-0.951057;0.000000;,
-0.000000;-1.000000;0.000000;,
-0.309017;-0.951056;0.000000;,
-0.587785;-0.809017;0.000000;,
-0.809017;-0.587785;0.000000;,
-0.951057;-0.309017;0.000000;,
-1.000000;0.000000;0.000000;,
-0.951057;0.309017;0.000000;,
-0.809017;0.587786;0.000000;,
-0.587785;0.809017;0.000000;,
-0.309017;0.951057;0.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;,
0.000000;0.000000;1.000000;;
120;
3;0,1,2;,
3;0,2,3;,
3;0,3,4;,
3;0,4,5;,
3;0,5,6;,
3;0,6,7;,
3;0,7,8;,
3;0,8,9;,
3;0,9,10;,
3;0,10,11;,
3;0,11,12;,
3;0,12,13;,
3;0,13,14;,
3;0,14,15;,
3;0,15,16;,
3;0,16,17;,
3;0,17,18;,
3;0,18,19;,
3;0,19,20;,
3;0,20,1;,
3;21,41,22;,
3;22,41,42;,
3;22,42,23;,
3;23,42,43;,
3;23,43,24;,
3;24,43,44;,
3;24,44,25;,
3;25,44,45;,
3;25,45,26;,
3;26,45,46;,
3;26,46,27;,
3;27,46,47;,
3;27,47,28;,
3;28,47,48;,
3;28,48,29;,
3;29,48,49;,
3;29,49,30;,
3;30,49,50;,
3;30,50,31;,
3;31,50,51;,
3;31,51,32;,
3;32,51,52;,
3;32,52,33;,
3;33,52,53;,
3;33,53,34;,
3;34,53,54;,
3;34,54,35;,
3;35,54,55;,
3;35,55,36;,
3;36,55,56;,
3;36,56,37;,
3;37,56,57;,
3;37,57,38;,
3;38,57,58;,
3;38,58,39;,
3;39,58,59;,
3;39,59,40;,
3;40,59,60;,
3;40,60,21;,
3;21,60,41;,
3;41,61,42;,
3;42,61,62;,
3;42,62,43;,
3;43,62,63;,
3;43,63,44;,
3;44,63,64;,
3;44,64,45;,
3;45,64,65;,
3;45,65,46;,
3;46,65,66;,
3;46,66,47;,
3;47,66,67;,
3;47,67,48;,
3;48,67,68;,
3;48,68,49;,
3;49,68,69;,
3;49,69,50;,
3;50,69,70;,
3;50,70,51;,
3;51,70,71;,
3;51,71,52;,
3;52,71,72;,
3;52,72,53;,
3;53,72,73;,
3;53,73,54;,
3;54,73,74;,
3;54,74,55;,
3;55,74,75;,
3;55,75,56;,
3;56,75,76;,
3;56,76,57;,
3;57,76,77;,
3;57,77,58;,
3;58,77,78;,
3;58,78,59;,
3;59,78,79;,
3;59,79,60;,
3;60,79,80;,
3;60,80,41;,
3;41,80,61;,
3;81,101,82;,
3;82,101,83;,
3;83,101,84;,
3;84,101,85;,
3;85,101,86;,
3;86,101,87;,
3;87,101,88;,
3;88,101,89;,
3;89,101,90;,
3;90,101,91;,
3;91,101,92;,
3;92,101,93;,
3;93,101,94;,
3;94,101,95;,
3;95,101,96;,
3;96,101,97;,
3;97,101,98;,
3;98,101,99;,
3;99,101,100;,
3;100,101,81;;
}
MeshMaterialList {
1;
120;
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0;
Material {
0.500000;0.500000;0.500000;0.000000;;
0.000000;
0.500000;0.500000;0.500000;;
0.000000;0.000000;0.000000;;
}
}
VertexDuplicationIndices {
102;
62;
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
101;
}
}
}

View File

@ -0,0 +1,936 @@
xof 0303txt 0032
template Frame {
<3d82ab46-62da-11cf-ab39-0020af71e433>
[...]
}
template Matrix4x4 {
<f6f23f45-7686-11cf-8f52-0040333594a3>
array FLOAT matrix[16];
}
template FrameTransformMatrix {
<f6f23f41-7686-11cf-8f52-0040333594a3>
Matrix4x4 frameMatrix;
}
template Vector {
<3d82ab5e-62da-11cf-ab39-0020af71e433>
FLOAT x;
FLOAT y;
FLOAT z;
}
template MeshFace {
<3d82ab5f-62da-11cf-ab39-0020af71e433>
DWORD nFaceVertexIndices;
array DWORD faceVertexIndices[nFaceVertexIndices];
}
template Mesh {
<3d82ab44-62da-11cf-ab39-0020af71e433>
DWORD nVertices;
array Vector vertices[nVertices];
DWORD nFaces;
array MeshFace faces[nFaces];
[...]
}
template MeshNormals {
<f6f23f43-7686-11cf-8f52-0040333594a3>
DWORD nNormals;
array Vector normals[nNormals];
DWORD nFaceNormals;
array MeshFace faceNormals[nFaceNormals];
}
template ColorRGBA {
<35ff44e0-6c7c-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
FLOAT alpha;
}
template ColorRGB {
<d3e16e81-7835-11cf-8f52-0040333594a3>
FLOAT red;
FLOAT green;
FLOAT blue;
}
template Material {
<3d82ab4d-62da-11cf-ab39-0020af71e433>
ColorRGBA faceColor;
FLOAT power;
ColorRGB specularColor;
ColorRGB emissiveColor;
[...]
}
template MeshMaterialList {
<f6f23f42-7686-11cf-8f52-0040333594a3>
DWORD nMaterials;
DWORD nFaceIndexes;
array DWORD faceIndexes[nFaceIndexes];
[Material <3d82ab4d-62da-11cf-ab39-0020af71e433>]
}
template VertexDuplicationIndices {
<b8d65549-d7c9-4995-89cf-53a9a8b031e3>
DWORD nIndices;
DWORD nOriginalVertices;
array DWORD indices[nIndices];
}
Frame {
FrameTransformMatrix {
1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000,0.000000,0.000000,0.000000,0.000000,1.000000;;
}
Mesh {
92;
0.000000;0.000000;1.000000;,
0.000000;0.309017;0.951057;,
0.181636;0.250000;0.951057;,
0.293893;0.095491;0.951057;,
0.293893;-0.095492;0.951057;,
0.181636;-0.250000;0.951057;,
-0.000000;-0.309017;0.951057;,
-0.181636;-0.250000;0.951057;,
-0.293893;-0.095491;0.951057;,
-0.293893;0.095492;0.951057;,
-0.181636;0.250000;0.951057;,
0.000000;0.587785;0.809017;,
0.345491;0.475528;0.809017;,
0.559017;0.181636;0.809017;,
0.559017;-0.181636;0.809017;,
0.345491;-0.475528;0.809017;,
-0.000000;-0.587785;0.809017;,
-0.345492;-0.475528;0.809017;,
-0.559017;-0.181635;0.809017;,
-0.559017;0.181636;0.809017;,
-0.345492;0.475528;0.809017;,
0.000000;0.809017;0.587785;,
0.475528;0.654509;0.587785;,
0.769421;0.250000;0.587785;,
0.769421;-0.250000;0.587785;,
0.475528;-0.654509;0.587785;,
-0.000000;-0.809017;0.587785;,
-0.475528;-0.654508;0.587785;,
-0.769421;-0.250000;0.587785;,
-0.769421;0.250000;0.587785;,
-0.475528;0.654508;0.587785;,
0.000000;0.951057;0.309017;,
0.559017;0.769421;0.309017;,
0.904509;0.293893;0.309017;,
0.904508;-0.293893;0.309017;,
0.559017;-0.769421;0.309017;,
-0.000000;-0.951057;0.309017;,
-0.559017;-0.769421;0.309017;,
-0.904509;-0.293892;0.309017;,
-0.904508;0.293893;0.309017;,
-0.559017;0.769421;0.309017;,
0.000000;1.000000;-0.000000;,
0.587785;0.809017;-0.000000;,
0.951057;0.309017;-0.000000;,
0.951056;-0.309017;-0.000000;,
0.587785;-0.809017;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.587785;-0.809017;-0.000000;,
-0.951057;-0.309017;-0.000000;,
-0.951056;0.309017;-0.000000;,
-0.587785;0.809017;-0.000000;,
0.000000;0.951056;-0.309017;,
0.559017;0.769421;-0.309017;,
0.904508;0.293893;-0.309017;,
0.904508;-0.293893;-0.309017;,
0.559017;-0.769421;-0.309017;,
-0.000000;-0.951056;-0.309017;,
-0.559017;-0.769421;-0.309017;,
-0.904509;-0.293892;-0.309017;,
-0.904508;0.293893;-0.309017;,
-0.559017;0.769421;-0.309017;,
0.000000;0.809017;-0.587785;,
0.475528;0.654508;-0.587785;,
0.769421;0.250000;-0.587785;,
0.769421;-0.250000;-0.587785;,
0.475528;-0.654508;-0.587785;,
-0.000000;-0.809017;-0.587785;,
-0.475528;-0.654508;-0.587785;,
-0.769421;-0.250000;-0.587785;,
-0.769421;0.250000;-0.587785;,
-0.475528;0.654508;-0.587785;,
0.000000;0.587785;-0.809017;,
0.345491;0.475528;-0.809017;,
0.559017;0.181636;-0.809017;,
0.559017;-0.181636;-0.809017;,
0.345491;-0.475528;-0.809017;,
-0.000000;-0.587785;-0.809017;,
-0.345492;-0.475528;-0.809017;,
-0.559017;-0.181635;-0.809017;,
-0.559017;0.181636;-0.809017;,
-0.345491;0.475528;-0.809017;,
0.000000;0.309017;-0.951056;,
0.181636;0.250000;-0.951056;,
0.293893;0.095492;-0.951056;,
0.293893;-0.095492;-0.951056;,
0.181636;-0.250000;-0.951056;,
-0.000000;-0.309017;-0.951056;,
-0.181636;-0.250000;-0.951056;,
-0.293893;-0.095491;-0.951056;,
-0.293893;0.095492;-0.951056;,
-0.181636;0.250000;-0.951056;,
0.000000;0.000000;-1.000000;;
180;
3;0,2,1;,
3;0,3,2;,
3;0,4,3;,
3;0,5,4;,
3;0,6,5;,
3;0,7,6;,
3;0,8,7;,
3;0,9,8;,
3;0,10,9;,
3;0,1,10;,
3;1,2,11;,
3;2,12,11;,
3;2,3,12;,
3;3,13,12;,
3;3,4,13;,
3;4,14,13;,
3;4,5,14;,
3;5,15,14;,
3;5,6,15;,
3;6,16,15;,
3;6,7,16;,
3;7,17,16;,
3;7,8,17;,
3;8,18,17;,
3;8,9,18;,
3;9,19,18;,
3;9,10,19;,
3;10,20,19;,
3;10,1,20;,
3;1,11,20;,
3;11,12,21;,
3;12,22,21;,
3;12,13,22;,
3;13,23,22;,
3;13,14,23;,
3;14,24,23;,
3;14,15,24;,
3;15,25,24;,
3;15,16,25;,
3;16,26,25;,
3;16,17,26;,
3;17,27,26;,
3;17,18,27;,
3;18,28,27;,
3;18,19,28;,
3;19,29,28;,
3;19,20,29;,
3;20,30,29;,
3;20,11,30;,
3;11,21,30;,
3;21,22,31;,
3;22,32,31;,
3;22,23,32;,
3;23,33,32;,
3;23,24,33;,
3;24,34,33;,
3;24,25,34;,
3;25,35,34;,
3;25,26,35;,
3;26,36,35;,
3;26,27,36;,
3;27,37,36;,
3;27,28,37;,
3;28,38,37;,
3;28,29,38;,
3;29,39,38;,
3;29,30,39;,
3;30,40,39;,
3;30,21,40;,
3;21,31,40;,
3;31,32,41;,
3;32,42,41;,
3;32,33,42;,
3;33,43,42;,
3;33,34,43;,
3;34,44,43;,
3;34,35,44;,
3;35,45,44;,
3;35,36,45;,
3;36,46,45;,
3;36,37,46;,
3;37,47,46;,
3;37,38,47;,
3;38,48,47;,
3;38,39,48;,
3;39,49,48;,
3;39,40,49;,
3;40,50,49;,
3;40,31,50;,
3;31,41,50;,
3;41,42,51;,
3;42,52,51;,
3;42,43,52;,
3;43,53,52;,
3;43,44,53;,
3;44,54,53;,
3;44,45,54;,
3;45,55,54;,
3;45,46,55;,
3;46,56,55;,
3;46,47,56;,
3;47,57,56;,
3;47,48,57;,
3;48,58,57;,
3;48,49,58;,
3;49,59,58;,
3;49,50,59;,
3;50,60,59;,
3;50,41,60;,
3;41,51,60;,
3;51,52,61;,
3;52,62,61;,
3;52,53,62;,
3;53,63,62;,
3;53,54,63;,
3;54,64,63;,
3;54,55,64;,
3;55,65,64;,
3;55,56,65;,
3;56,66,65;,
3;56,57,66;,
3;57,67,66;,
3;57,58,67;,
3;58,68,67;,
3;58,59,68;,
3;59,69,68;,
3;59,60,69;,
3;60,70,69;,
3;60,51,70;,
3;51,61,70;,
3;61,62,71;,
3;62,72,71;,
3;62,63,72;,
3;63,73,72;,
3;63,64,73;,
3;64,74,73;,
3;64,65,74;,
3;65,75,74;,
3;65,66,75;,
3;66,76,75;,
3;66,67,76;,
3;67,77,76;,
3;67,68,77;,
3;68,78,77;,
3;68,69,78;,
3;69,79,78;,
3;69,70,79;,
3;70,80,79;,
3;70,61,80;,
3;61,71,80;,
3;71,72,81;,
3;72,82,81;,
3;72,73,82;,
3;73,83,82;,
3;73,74,83;,
3;74,84,83;,
3;74,75,84;,
3;75,85,84;,
3;75,76,85;,
3;76,86,85;,
3;76,77,86;,
3;77,87,86;,
3;77,78,87;,
3;78,88,87;,
3;78,79,88;,
3;79,89,88;,
3;79,80,89;,
3;80,90,89;,
3;80,71,90;,
3;71,81,90;,
3;81,82,91;,
3;82,83,91;,
3;83,84,91;,
3;84,85,91;,
3;85,86,91;,
3;86,87,91;,
3;87,88,91;,
3;88,89,91;,
3;89,90,91;,
3;90,81,91;;
MeshNormals {
92;
0.000000;0.000000;1.000000;,
0.000000;0.309017;0.951057;,
0.181636;0.250000;0.951057;,
0.293893;0.095491;0.951057;,
0.293893;-0.095492;0.951057;,
0.181636;-0.250000;0.951057;,
-0.000000;-0.309017;0.951057;,
-0.181636;-0.250000;0.951057;,
-0.293893;-0.095491;0.951057;,
-0.293893;0.095492;0.951057;,
-0.181636;0.250000;0.951057;,
0.000000;0.587785;0.809017;,
0.345491;0.475528;0.809017;,
0.559017;0.181636;0.809017;,
0.559017;-0.181636;0.809017;,
0.345491;-0.475528;0.809017;,
-0.000000;-0.587785;0.809017;,
-0.345492;-0.475528;0.809017;,
-0.559017;-0.181635;0.809017;,
-0.559017;0.181636;0.809017;,
-0.345492;0.475528;0.809017;,
0.000000;0.809017;0.587785;,
0.475528;0.654509;0.587785;,
0.769421;0.250000;0.587785;,
0.769421;-0.250000;0.587785;,
0.475528;-0.654509;0.587785;,
-0.000000;-0.809017;0.587785;,
-0.475528;-0.654508;0.587785;,
-0.769421;-0.250000;0.587785;,
-0.769421;0.250000;0.587785;,
-0.475528;0.654508;0.587785;,
0.000000;0.951057;0.309017;,
0.559017;0.769421;0.309017;,
0.904509;0.293893;0.309017;,
0.904508;-0.293893;0.309017;,
0.559017;-0.769421;0.309017;,
-0.000000;-0.951057;0.309017;,
-0.559017;-0.769421;0.309017;,
-0.904509;-0.293892;0.309017;,
-0.904508;0.293893;0.309017;,
-0.559017;0.769421;0.309017;,
0.000000;1.000000;-0.000000;,
0.587785;0.809017;-0.000000;,
0.951057;0.309017;-0.000000;,
0.951056;-0.309017;-0.000000;,
0.587785;-0.809017;-0.000000;,
-0.000000;-1.000000;-0.000000;,
-0.587785;-0.809017;-0.000000;,
-0.951057;-0.309017;-0.000000;,
-0.951056;0.309017;-0.000000;,
-0.587785;0.809017;-0.000000;,
0.000000;0.951056;-0.309017;,
0.559017;0.769421;-0.309017;,
0.904508;0.293893;-0.309017;,
0.904508;-0.293893;-0.309017;,
0.559017;-0.769421;-0.309017;,
-0.000000;-0.951056;-0.309017;,
-0.559017;-0.769421;-0.309017;,
-0.904509;-0.293892;-0.309017;,
-0.904508;0.293893;-0.309017;,
-0.559017;0.769421;-0.309017;,
0.000000;0.809017;-0.587785;,
0.475528;0.654508;-0.587785;,
0.769421;0.250000;-0.587785;,
0.769421;-0.250000;-0.587785;,
0.475528;-0.654508;-0.587785;,
-0.000000;-0.809017;-0.587785;,
-0.475528;-0.654508;-0.587785;,
-0.769421;-0.250000;-0.587785;,
-0.769421;0.250000;-0.587785;,
-0.475528;0.654508;-0.587785;,
0.000000;0.587785;-0.809017;,
0.345491;0.475528;-0.809017;,
0.559017;0.181636;-0.809017;,
0.559017;-0.181636;-0.809017;,
0.345491;-0.475528;-0.809017;,
-0.000000;-0.587785;-0.809017;,
-0.345492;-0.475528;-0.809017;,
-0.559017;-0.181635;-0.809017;,
-0.559017;0.181636;-0.809017;,
-0.345491;0.475528;-0.809017;,
0.000000;0.309017;-0.951056;,
0.181636;0.250000;-0.951056;,
0.293893;0.095492;-0.951056;,
0.293893;-0.095492;-0.951056;,
0.181636;-0.250000;-0.951056;,
-0.000000;-0.309017;-0.951056;,
-0.181636;-0.250000;-0.951056;,
-0.293893;-0.095491;-0.951056;,
-0.293893;0.095492;-0.951056;,
-0.181636;0.250000;-0.951056;,
0.000000;0.000000;-1.000000;;
180;
3;0,2,1;,
3;0,3,2;,
3;0,4,3;,
3;0,5,4;,
3;0,6,5;,
3;0,7,6;,
3;0,8,7;,
3;0,9,8;,
3;0,10,9;,
3;0,1,10;,
3;1,2,11;,
3;2,12,11;,
3;2,3,12;,
3;3,13,12;,
3;3,4,13;,
3;4,14,13;,
3;4,5,14;,
3;5,15,14;,
3;5,6,15;,
3;6,16,15;,
3;6,7,16;,
3;7,17,16;,
3;7,8,17;,
3;8,18,17;,
3;8,9,18;,
3;9,19,18;,
3;9,10,19;,
3;10,20,19;,
3;10,1,20;,
3;1,11,20;,
3;11,12,21;,
3;12,22,21;,
3;12,13,22;,
3;13,23,22;,
3;13,14,23;,
3;14,24,23;,
3;14,15,24;,
3;15,25,24;,
3;15,16,25;,
3;16,26,25;,
3;16,17,26;,
3;17,27,26;,
3;17,18,27;,
3;18,28,27;,
3;18,19,28;,
3;19,29,28;,
3;19,20,29;,
3;20,30,29;,
3;20,11,30;,
3;11,21,30;,
3;21,22,31;,
3;22,32,31;,
3;22,23,32;,
3;23,33,32;,
3;23,24,33;,
3;24,34,33;,
3;24,25,34;,
3;25,35,34;,
3;25,26,35;,
3;26,36,35;,
3;26,27,36;,
3;27,37,36;,
3;27,28,37;,
3;28,38,37;,
3;28,29,38;,
3;29,39,38;,
3;29,30,39;,
3;30,40,39;,
3;30,21,40;,
3;21,31,40;,
3;31,32,41;,
3;32,42,41;,
3;32,33,42;,
3;33,43,42;,
3;33,34,43;,
3;34,44,43;,
3;34,35,44;,
3;35,45,44;,
3;35,36,45;,
3;36,46,45;,
3;36,37,46;,
3;37,47,46;,
3;37,38,47;,
3;38,48,47;,
3;38,39,48;,
3;39,49,48;,
3;39,40,49;,
3;40,50,49;,
3;40,31,50;,
3;31,41,50;,
3;41,42,51;,
3;42,52,51;,
3;42,43,52;,
3;43,53,52;,
3;43,44,53;,
3;44,54,53;,
3;44,45,54;,
3;45,55,54;,
3;45,46,55;,
3;46,56,55;,
3;46,47,56;,
3;47,57,56;,
3;47,48,57;,
3;48,58,57;,
3;48,49,58;,
3;49,59,58;,
3;49,50,59;,
3;50,60,59;,
3;50,41,60;,
3;41,51,60;,
3;51,52,61;,
3;52,62,61;,
3;52,53,62;,
3;53,63,62;,
3;53,54,63;,
3;54,64,63;,
3;54,55,64;,
3;55,65,64;,
3;55,56,65;,
3;56,66,65;,
3;56,57,66;,
3;57,67,66;,
3;57,58,67;,
3;58,68,67;,
3;58,59,68;,
3;59,69,68;,
3;59,60,69;,
3;60,70,69;,
3;60,51,70;,
3;51,61,70;,
3;61,62,71;,
3;62,72,71;,
3;62,63,72;,
3;63,73,72;,
3;63,64,73;,
3;64,74,73;,
3;64,65,74;,
3;65,75,74;,
3;65,66,75;,
3;66,76,75;,
3;66,67,76;,
3;67,77,76;,
3;67,68,77;,
3;68,78,77;,
3;68,69,78;,
3;69,79,78;,
3;69,70,79;,
3;70,80,79;,
3;70,61,80;,
3;61,71,80;,
3;71,72,81;,
3;72,82,81;,
3;72,73,82;,
3;73,83,82;,
3;73,74,83;,
3;74,84,83;,
3;74,75,84;,
3;75,85,84;,
3;75,76,85;,
3;76,86,85;,
3;76,77,86;,
3;77,87,86;,
3;77,78,87;,
3;78,88,87;,
3;78,79,88;,
3;79,89,88;,
3;79,80,89;,
3;80,90,89;,
3;80,71,90;,
3;71,81,90;,
3;81,82,91;,
3;82,83,91;,
3;83,84,91;,
3;84,85,91;,
3;85,86,91;,
3;86,87,91;,
3;87,88,91;,
3;88,89,91;,
3;89,90,91;,
3;90,81,91;;
}
MeshMaterialList {
1;
180;
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0,
0;
Material {
0.500000;0.500000;0.500000;0.000000;;
0.000000;
0.500000;0.500000;0.500000;;
0.000000;0.000000;0.000000;;
}
}
VertexDuplicationIndices {
92;
92;
0,
1,
2,
3,
4,
5,
6,
7,
8,
9,
10,
11,
12,
13,
14,
15,
16,
17,
18,
19,
20,
21,
22,
23,
24,
25,
26,
27,
28,
29,
30,
31,
32,
33,
34,
35,
36,
37,
38,
39,
40,
41,
42,
43,
44,
45,
46,
47,
48,
49,
50,
51,
52,
53,
54,
55,
56,
57,
58,
59,
60,
61,
62,
63,
64,
65,
66,
67,
68,
69,
70,
71,
72,
73,
74,
75,
76,
77,
78,
79,
80,
81,
82,
83,
84,
85,
86,
87,
88,
89,
90,
91;
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -0,0 +1,71 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
using XnaDevRu.BulletX;
using XnaDevRu.BulletX.Dynamics;
namespace XnaDevRu.BulletX.Demos.Basic
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class BasicDemo : XnaDevRu.BulletX.Demos.DemoGame
{
public BasicDemo()
{
SphereBoxCollisionAlgorithm.CreateFunc boxAlgo = new SphereBoxCollisionAlgorithm.CreateFunc();
boxAlgo.IsSwapped = true;
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Sphere, BroadphaseNativeTypes.Sphere, new SphereSphereCollisionAlgorithm.CreateFunc());
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Sphere, BroadphaseNativeTypes.Box, new SphereBoxCollisionAlgorithm.CreateFunc());
CollisionDispatcher.RegisterCollisionCreateFunc(BroadphaseNativeTypes.Box, BroadphaseNativeTypes.Sphere, boxAlgo);
Shapes[0] = new SphereShape(50);
Shapes[2] = new SphereShape(HalfExtents - CollisionMargin);
Matrix tr = Matrix.Identity;
tr.Translation = new Vector3(0, -50, 0);
CreateRigidBody(0, tr, Shapes[0]);
for (int i = 0; i < NumObjects; i++)
{
Shapes[2].Margin = CollisionMargin;
int colsize = 2;
int row = (int)((i * HalfExtents * 2) / (colsize * 2 * HalfExtents));
int row2 = row;
int col = i % colsize - colsize / 2;
tr.Translation = new Vector3(col * 2 * HalfExtents + (row2 % 2) * HalfExtents,
row * 2 * HalfExtents + HalfExtents, 0);
CreateRigidBody(1, tr, Shapes[2]);
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
namespace XnaDevRu.BulletX.Demos.Basic
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (BasicDemo game = new BasicDemo())
{
game.Run();
}
}
}
}

View File

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Basic")]
[assembly: AssemblyProduct("Bullet for XNA")]
[assembly: AssemblyDescription("Bullet for XNA Basic Demo")]
[assembly: AssemblyCompany("XNADev.ru")]
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("dd847e80-8cf8-4c43-91cd-524301838768")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.149.21894")]

View File

@ -0,0 +1,97 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{72384342-889C-47B0-B98E-C855D1CE0F41}</ProjectGuid>
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>XnaDevRu.BulletX.Demos.Basic</RootNamespace>
<AssemblyName>Basic</AssemblyName>
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
<XNAProjectContentPipelineAssemblies>
</XNAProjectContentPipelineAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game">
<Private>False</Private>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>Program</Name>
</Compile>
<Compile Include="BasicDemo.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>BasicDemo</Name>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
<Link>bullet_ico.ico</Link>
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>bullet_ico</Name>
</Content>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
<Name>XnaDevRu.BulletX.Demos</Name>
</ProjectReference>
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
<Project>{5BEE189F-47A1-42A8-A297-1960221BE20D}</Project>
<Name>XnaDevRu.BulletX</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
<ProjectExtensions>
<VisualStudio>
</VisualStudio>
</ProjectExtensions>
</Project>

View File

@ -0,0 +1,108 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
using XnaDevRu.BulletX;
using XnaDevRu.BulletX.Dynamics;
namespace XnaDevRu.BulletX.Demos.Ccd
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class CcdDemo : XnaDevRu.BulletX.Demos.DemoGame
{
public CcdDemo()
{
NumObjects = 120;
Shapes[0] = new BoxShape(new Vector3(200, 10, 200));
for (int i = 0; i < NumObjects; i++)
{
CollisionShape shape = Shapes[ShapeIndex[i]];
shape.Margin = CollisionMargin;
bool isDynamic = i > 0;
Matrix trans = Matrix.Identity;
if (i > 0)
{
//stack them
int colsize = 10;
int row = (i * HalfExtents * 2) / (colsize * 2 * HalfExtents);
int row2 = row;
int col = (i) % (colsize) - colsize / 2;
if (col > 3)
{
col = 11;
row2 |= 1;
}
Vector3 pos;
if (NumObjects > 2)
{
pos = new Vector3(col * 2 * HalfExtents + (row2 % 2) * HalfExtents,
row * 2 * HalfExtents + HalfExtents + ExtraHeight, 0);
}
else
{
pos = new Vector3(0, -30, 0);
}
if (shape is BoxShape)
{
trans.Right = new Vector3(0, -1, 0);
trans.Up = new Vector3(1, 0, 0);
trans.Backward = new Vector3(0, 0, 1);
}
trans *= Matrix.CreateRotationZ(Microsoft.Xna.Framework.MathHelper.PiOver2);
trans.Translation = pos;
}
else
{
trans.Translation = new Vector3(0, -30, 0);
}
float mass = 1.0f;
if (!isDynamic)
mass = 0.0f;
RigidBody body = CreateRigidBody(mass, trans, shape);
body.CcdSquareMotionThreshold = HalfExtents;
body.CcdSweptSphereRadius = 0.2f * HalfExtents;
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
namespace XnaDevRu.BulletX.Demos.Ccd
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (CcdDemo game = new CcdDemo())
{
game.Run();
}
}
}
}

View File

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Ccd")]
[assembly: AssemblyProduct("Bullet for XNA")]
[assembly: AssemblyDescription("Bullet for XNA CCD Demo")]
[assembly: AssemblyCompany("XNADev.ru")]
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("58969560-d588-4200-a57e-2f312cdf6a18")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.149.21894")]

View File

@ -0,0 +1,93 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{705FCCF1-44C8-430E-92A9-9987CD3D6A64}</ProjectGuid>
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>XnaDevRu.BulletX.Demos.Ccd</RootNamespace>
<AssemblyName>Ccd</AssemblyName>
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
<XNAProjectContentPipelineAssemblies>
</XNAProjectContentPipelineAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game">
<Private>False</Private>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="CcdDemo.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>CcdDemo</Name>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>Program</Name>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
<Name>XnaDevRu.BulletX.Demos</Name>
</ProjectReference>
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
<Project>{EBC5D108-65E5-4F8E-B3F2-BF7EE56C27F3}</Project>
<Name>XnaDevRu.BulletX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
<Link>bullet_ico.ico</Link>
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>bullet_ico</Name>
</Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,121 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
using XnaDevRu.BulletX;
using XnaDevRu.BulletX.Dynamics;
namespace XnaDevRu.BulletX.Demos.Constraints
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class ConstraintDemo : XnaDevRu.BulletX.Demos.DemoGame
{
Matrix _sliderTransform;
Vector3 _lowerSliderLimit = new Vector3(-10, 0, 0);
Vector3 _hiSliderLimit = new Vector3(10, 0, 0);
RigidBody _d6BodyA = null;
public ConstraintDemo()
{
CollisionShape shape = new BoxShape(new Vector3(HalfExtents, HalfExtents, HalfExtents));
Matrix trans = Matrix.Identity;
trans.Translation = new Vector3(0, 20, 0);
float mass = 1f;
//Point to Point constraint (ball socket)
{
RigidBody bodyA = CreateRigidBody(mass, trans, shape);
trans.Translation = new Vector3(2 * HalfExtents, 20, 0);
mass = 1f;
RigidBody bodyB = null;
//RigidBody bodyB = CreateRigidBody(mass, trans, shape);
//bodyB.ActivationState = ActivationState.DisableDeactivation;
//bodyB.SetDamping(0.3f, 0.3f);
Vector3 pivotInA = new Vector3(HalfExtents, -HalfExtents, -HalfExtents);
Vector3 axisInA = new Vector3(0, 0, 1);
Vector3 pivotInB = bodyB != null ? MathHelper.MatrixToVector(MathHelper.InvertMatrix(bodyB.CenterOfMassTransform), MathHelper.MatrixToVector(bodyA.CenterOfMassTransform, pivotInA)) : pivotInA;
Vector3 axisInB = bodyB != null ?
Vector3.TransformNormal(Vector3.TransformNormal(axisInA, bodyB.CenterOfMassTransform), MathHelper.InvertMatrix(bodyB.CenterOfMassTransform)) :
Vector3.TransformNormal(axisInA, bodyA.CenterOfMassTransform);
//TypedConstraint p2p = new Point2PointConstraint(bodyA, bodyB, pivotInA, pivotInB);
//TypedConstraint hinge = new HingeConstraint(bodyA, bodyB, pivotInA, pivotInB, axisInA, axisInB);
HingeConstraint hinge = new HingeConstraint(bodyA, pivotInA, axisInA);
//use zero targetVelocity and a small maxMotorImpulse to simulate joint friction
//float targetVelocity = 0.0f;
//float maxMotorImpulse = 0.01;
float targetVelocity = 1.0f;
float maxMotorImpulse = 1.0f;
hinge.EnableAngularMotor(true, targetVelocity, maxMotorImpulse);
PhysicsWorld.AddConstraint(hinge);
}
// create a slider, using the generic D6 constraint
{
mass = 1f;
Vector3 sliderWorldPos = new Vector3(0, 10, 0);
Vector3 sliderAxis = new Vector3(1, 0, 0);
float angle = 0;
Matrix sliderOrientation = Matrix.CreateFromQuaternion(new Quaternion(sliderAxis, angle));
trans = Matrix.Identity;
trans.Translation = sliderWorldPos;
//trans.setBasis(sliderOrientation);
_sliderTransform = trans;
_d6BodyA = CreateRigidBody(mass, trans, shape);
_d6BodyA.ActivationState = ActivationState.DisableDeactivation;
RigidBody fixedBody1 = CreateRigidBody(0, trans, null);
Matrix frameInA, frameInB;
frameInA = Matrix.Identity;
frameInB = Matrix.Identity;
Generic6DofConstraint slider = new Generic6DofConstraint(_d6BodyA, fixedBody1, frameInA, frameInB);
slider.SetLinearLowerLimit(_lowerSliderLimit);
slider.SetLinearUpperLimit(_hiSliderLimit);
//range should be small, otherwise singularities will 'explode' the constraint
slider.SetAngularLowerLimit(new Vector3(10, 0, 0));
slider.SetAngularUpperLimit(new Vector3(0, 0, 0));
PhysicsWorld.AddConstraint(slider);
}
}
}
}

View File

@ -0,0 +1,40 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
namespace XnaDevRu.BulletX.Demos.Constraints
{
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
using (ConstraintDemo game = new ConstraintDemo())
{
game.Run();
}
}
}
}

View File

@ -0,0 +1,33 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos.Constraints")]
[assembly: AssemblyProduct("Bullet for XNA")]
[assembly: AssemblyDescription("Bullet for XNA Constraint Demo")]
[assembly: AssemblyCompany("XNADev.ru")]
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("1c75580e-8bd8-47cd-8124-0e0054125840")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.149.21894")]

View File

@ -0,0 +1,93 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{77ABF9BD-E838-4EF0-BD76-C656C62BC517}</ProjectGuid>
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>XnaDevRu.BulletX.Demos.Constraints</RootNamespace>
<AssemblyName>Constraints</AssemblyName>
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<ApplicationIcon>..\..\..\SharedContent\bullet_ico.ico</ApplicationIcon>
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
<XNAProjectContentPipelineAssemblies>
</XNAProjectContentPipelineAssemblies>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\Build\x86\Debug\Demos\BulletX\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\Build\x86\Release\Demos\BulletX\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game">
<Private>False</Private>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="ConstraintDemo.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>ConstraintDemo</Name>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Program.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>Program</Name>
</Compile>
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\XnaDevRu.BulletX.Demos\XnaDevRu.BulletX.Demos.csproj">
<Project>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</Project>
<Name>XnaDevRu.BulletX.Demos</Name>
</ProjectReference>
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
<Project>{EBC5D108-65E5-4F8E-B3F2-BF7EE56C27F3}</Project>
<Name>XnaDevRu.BulletX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\SharedContent\bullet_ico.ico">
<Link>bullet_ico.ico</Link>
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>bullet_ico</Name>
</Content>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,589 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
#region Using Statements
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
#endregion
using XnaDevRu.Demos;
using XnaDevRu.BulletX;
using XnaDevRu.BulletX.Dynamics;
namespace XnaDevRu.BulletX.Demos
{
/// <summary>
/// This is the main type for your BulletX Demo.
/// </summary>
public class DemoGame : Microsoft.Xna.Framework.Game
{
// Main elements
private GraphicsDeviceManager _graphics;
private ContentManager _content;
// Components
private Camera _camera;
private Framerate _fps;
private MouseState _prevMouseState;
// Picking
private TypedConstraint _pickConstraint;
private Vector3 _oldPickingPos;
private float _oldPickingDist = 0f;
private RigidBody _pickedBody = null; //for deactivation state
//Physics
private CollisionDispatcher _collisionDispatcher;
private OverlappingPairCache _broadphase;
private SequentialImpulseConstraintSolver _solver;
private DiscreteDynamicsWorld _world;
private CollisionShape[] _shapePtr;
private const int _maxNumObjects = 32760;
private int _numObjects = 120;
private const int _cubeHalfExtent = 1;
private const int _extraHeight = -20;
private const float _collisionMargin = 0.05f;
private float _shootBoxInitialSpeed = 50f;
private int[] _shapeIndex;
private Model _modelBox;
private Model _modelSphere;
private Model _modelCylinder;
private bool _useDebugDrawer;
private bool _useSweepAndPrune = true;
/// <summary>
/// Initializes new Demo testbed.
/// </summary>
public DemoGame()
{
_graphics = new GraphicsDeviceManager(this);
_content = new ContentManager(Services);
//graphics.SynchronizeWithVerticalRetrace = false;
IsMouseVisible = true;
_camera = new Camera(this);
_fps = new Framerate(this);
_fps.UpdateFrequency = 100;
Components.Add(_camera);
Components.Add(_fps);
ResetPhysics();
}
/// <summary>
/// Gets graphics device manager associated with this demo.
/// </summary>
public GraphicsDeviceManager Graphics { get { return _graphics; } }
/// <summary>
/// Gets content manager associated with this demo.
/// </summary>
public ContentManager Content { get { return _content; } }
/// <summary>
/// Gets camera component associated with this demo.
/// </summary>
public Camera Camera { get { return _camera; } }
/// <summary>
/// Gets framerate component associated with this demo.
/// </summary>
public Framerate Fps { get { return _fps; } }
/// <summary>
/// Gets or sets current collision dispatcher.
/// </summary>
public CollisionDispatcher CollisionDispatcher { get { return _collisionDispatcher; } set { _collisionDispatcher = value; } }
/// <summary>
/// Gets or sets current overlapping pair cache.
/// </summary>
public OverlappingPairCache Broadphase { get { return _broadphase; } set { _broadphase = value; } }
/// <summary>
/// Gets or sets current sequential impulse constraint solver.
/// </summary>
public SequentialImpulseConstraintSolver Solver { get { return _solver; } set { _solver = value; } }
/// <summary>
/// Gets or sets current dynamics world.
/// </summary>
public DiscreteDynamicsWorld PhysicsWorld { get { return _world; } set { _world = value; } }
/// <summary>
/// Gets or sets predefined shape array.
/// </summary>
public CollisionShape[] Shapes { get { return _shapePtr; } set { _shapePtr = value; } }
/// <summary>
/// Gets max number of objects in the simulation.
/// </summary>
public int MaxNumObjects { get { return _maxNumObjects; } }
/// <summary>
/// Gets or sets starting objects count in simulation.
/// </summary>
public int NumObjects { get { return _numObjects; } set { _numObjects = value; } }
/// <summary>
/// Gets half extents.
/// </summary>
public int HalfExtents { get { return _cubeHalfExtent; } }
/// <summary>
/// Gets extra height.
/// </summary>
public int ExtraHeight { get { return _extraHeight; } }
/// <summary>
/// Gets collision margin.
/// </summary>
public float CollisionMargin { get { return _collisionMargin; } }
/// <summary>
/// Gets or sets initial box speed when shot.
/// </summary>
public float ShootBoxInitialSpeed { get { return _shootBoxInitialSpeed; } set { _shootBoxInitialSpeed = value; } }
/// <summary>
/// Gets or sets predefined shape index reference for simulated objects.
/// </summary>
public int[] ShapeIndex { get { return _shapeIndex; } set { _shapeIndex = value; } }
/// <summary>
/// Gets or sets box model.
/// </summary>
public Model ModelBox { get { return _modelBox; } set { _modelBox = value; } }
/// <summary>
/// Gets or sets sphere model.
/// </summary>
public Model ModelSphere { get { return _modelSphere; } set { _modelSphere = value; } }
/// <summary>
/// Gets or sets cylinder model.
/// </summary>
public Model ModelCylinder { get { return _modelCylinder; } set { _modelCylinder = value; } }
/// <summary>
/// Gets or sets the ability to draw debug information.
/// </summary>
public bool UseDebugDrawer { get { return _useDebugDrawer; } set { _useDebugDrawer = value; } }
/// <summary>
/// Gets or sets the sweep and prune for broadphase.
/// </summary>
public bool UseSweepAndPrune { get { return _useSweepAndPrune; } set { _useSweepAndPrune = value; } }
/// <summary>
/// Reinitializes physics.
/// </summary>
public void ResetPhysics()
{
_collisionDispatcher = new CollisionDispatcher();
if (_useSweepAndPrune)
{
Vector3 worldAabbMin = new Vector3(-10000, -10000, -10000);
Vector3 worldAabbMax = new Vector3(10000, 10000, 10000);
const int maxProxies = 32766;
_broadphase = new AxisSweep3(worldAabbMin, worldAabbMax, maxProxies);
}
else
_broadphase = new SimpleBroadphase();
_solver = new SequentialImpulseConstraintSolver();
_world = new DiscreteDynamicsWorld(_collisionDispatcher, _broadphase, _solver);
//world.setConstraintSolver(solver);
_world.Gravity = new Vector3(0, -10, 0);
_shapePtr = new CollisionShape[4];
_shapePtr[0] = new BoxShape(new Vector3(50, 10, 50));
_shapePtr[1] = new CylinderShape(new Vector3(_cubeHalfExtent - _collisionMargin, _cubeHalfExtent - _collisionMargin, _cubeHalfExtent - _collisionMargin));
_shapePtr[2] = new SphereShape(_cubeHalfExtent);
_shapePtr[3] = new BoxShape(new Vector3(_cubeHalfExtent, _cubeHalfExtent, _cubeHalfExtent));
_shapeIndex = new int[_maxNumObjects];
Matrix tr = Matrix.Identity;
for (int i = 0; i < _numObjects; i++)
{
if (i > 0)
// set shape
_shapeIndex[i] = 1;
else
_shapeIndex[i] = 0;
}
GC.Collect();
}
/// <summary>
/// Creates new rigid body and adds it to the world.
/// </summary>
/// <param name="mass">Body mass, if 0 body is static.</param>
/// <param name="startTransform">Starting body transform.</param>
/// <param name="shape">Body shape.</param>
/// <returns>Created rigid body.</returns>
public RigidBody CreateRigidBody(float mass, Matrix startTransform, CollisionShape shape)
{
//rigidbody is dynamic if and only if mass is non zero, otherwise static
bool isDynamic = (mass != 0.0f);
Vector3 localInertia = new Vector3();
if (isDynamic)
shape.CalculateLocalInertia(mass, out localInertia);
//using motionstate is recommended, it provides interpolation capabilities, and only synchronizes 'active' objects
DefaultMotionState myMotionState = new DefaultMotionState(startTransform, Matrix.Identity);
RigidBody body = new RigidBody(mass, myMotionState, shape, localInertia, 0.0f, 0.0f, 0.5f, 0.0f);
_world.AddRigidBody(body);
return body;
}
/// <summary>
/// Called after the Game and Graphics.GraphicsDevice are created, but before Game.LoadGraphicsContent.
/// </summary>
protected override void Initialize()
{
base.Initialize();
_camera.Position = new Vector3(0, 3, 75);
_camera.Target = new Vector3(0, 0, 0);
if (_useDebugDrawer)
{
XnaDebugDraw dbg = new XnaDebugDraw(_graphics.GraphicsDevice);
dbg.DebugMode = DebugDrawModes.DrawAabb | DebugDrawModes.DrawContactPoints;
_world.DebugDrawer = dbg;
}
}
/// <summary>
/// Loads graphics content needed by this demo.
/// </summary>
/// <param name="loadAllContent">If need to reload all content.</param>
protected override void LoadGraphicsContent(bool loadAllContent)
{
if (loadAllContent)
{
_modelBox = _content.Load<Model>("content\\box");
_modelSphere = _content.Load<Model>("content\\sphere");
_modelCylinder = _content.Load<Model>("content\\cylinder");
}
}
/// <summary>
/// Unloads graphics content needed by this demo.
/// </summary>
/// <param name="unloadAllContent">If need to unload all content.</param>
protected override void UnloadGraphicsContent(bool unloadAllContent)
{
if (unloadAllContent == true)
{
_content.Unload();
}
}
/// <summary>
/// Called when the game has determined that game logic needs to be processed.
/// </summary>
/// <param name="gameTime">Time passed since the last call to this function.</param>
protected override void Update(GameTime gameTime)
{
MouseState mouseState = Mouse.GetState();
Vector3 rayTo = getRayTo(mouseState.X, mouseState.Y);
if (mouseState.LeftButton == ButtonState.Pressed && _prevMouseState.LeftButton == ButtonState.Released)
{
shootBox(rayTo);
}
if (mouseState.MiddleButton == ButtonState.Pressed && _prevMouseState.MiddleButton == ButtonState.Released)
{
if (_world != null)
{
CollisionWorld.ClosestRayResultCallback rayCallback = new CollisionWorld.ClosestRayResultCallback(_camera.Position, rayTo);
_world.RayTest(_camera.Position, rayTo, rayCallback);
if (rayCallback.HasHit)
{
RigidBody body = RigidBody.Upcast(rayCallback.CollisionObject);
if (body != null)
{
//other exclusions?
if (!(body.IsStaticObject || body.IsKinematicObject))
{
_pickedBody = body;
_pickedBody.ActivationState = ActivationState.DisableDeactivation;
Vector3 pickPos = rayCallback.HitPointWorld;
Vector3 localPivot = Vector3.Transform(pickPos, XnaDevRu.BulletX.MathHelper.InvertMatrix(body.CenterOfMassTransform));
Point2PointConstraint p2p = new Point2PointConstraint(body, localPivot);
_world.AddConstraint(p2p);
_pickConstraint = p2p;
//save mouse position for dragging
_oldPickingPos = rayTo;
Vector3 eyePos = new Vector3(_camera.Position.X, _camera.Position.Y, _camera.Position.Z);
_oldPickingDist = (eyePos - pickPos).Length();
//very weak constraint for picking
p2p.Settings.Tau = 1.1f;
}
}
}
}
}
else if (mouseState.MiddleButton == ButtonState.Released && _prevMouseState.MiddleButton == ButtonState.Pressed)
{
if (_pickConstraint != null && _world != null)
{
_world.RemoveConstraint(_pickConstraint);
_pickConstraint = null;
_pickedBody.ForceActivationState(ActivationState.Active);
_pickedBody.DeactivationTime = 0f;
_pickedBody = null;
}
}
if (_pickConstraint != null)
{
//move the constraint pivot
Point2PointConstraint p2p = _pickConstraint as Point2PointConstraint;
if (p2p != null)
{
//keep it at the same picking distance
Vector3 dir = rayTo - _camera.Position;
dir.Normalize();
dir *= _oldPickingDist;
Vector3 newPos = _camera.Position + dir;
p2p.PivotInB = newPos;
}
}
_prevMouseState = mouseState;
if (Keyboard.GetState().IsKeyDown(Keys.Space))
{
//world.stepSimulation(1.0f/60.0f,0);
int numObjects = _world.CollisionObjectsCount;
for (int i = 0; i < numObjects; i++)
{
CollisionObject colObj = _world.CollisionObjects[i];
RigidBody body = RigidBody.Upcast(colObj);
if (body != null)
{
if (body.MotionState != null)
{
DefaultMotionState myMotionState = (DefaultMotionState)body.MotionState;
myMotionState.GraphicsWorldTransform = myMotionState.StartWorldTransform;
colObj.WorldTransform = myMotionState.GraphicsWorldTransform;
colObj.InterpolationWorldTransform = myMotionState.StartWorldTransform;
colObj.Activate();
}
//removed cached contact points
_world.Broadphase.CleanProxyFromPairs(colObj.Broadphase);
if (body != null && !body.IsStaticObject)
{
RigidBody.Upcast(colObj).LinearVelocity = new Vector3(0, 0, 0);
RigidBody.Upcast(colObj).AngularVelocity = new Vector3(0, 0, 0);
}
}
}
}
else if (Keyboard.GetState().IsKeyDown(Keys.Escape) || GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
{
Exit();
}
else
{
//world.stepSimulation(1.0f / 60.0f, 1);
}
base.Update(gameTime);
}
/// <summary>
/// Called when the gamedetermines it is time to draw a frame.
/// </summary>
/// <param name="gameTime">Time passed since the last call to this function.</param>
protected override void Draw(GameTime gameTime)
{
_graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
if (_useDebugDrawer)
((XnaDebugDraw)_world.DebugDrawer).Update(_camera.View, _camera.Projection);
_world.StepSimulation(1.0f / 60.0f, 1);
Matrix objMatrix;
if (_world != null)
{
int numObjects = _world.CollisionObjectsCount;
Vector3 wireColor = Vector3.UnitX;
for (int i = 0; i < numObjects; i++)
{
CollisionObject colObj = _world.CollisionObjects[i];
RigidBody body = RigidBody.Upcast(colObj);
if (body != null && body.MotionState != null)
{
DefaultMotionState myMotionState = (DefaultMotionState)body.MotionState;
objMatrix = myMotionState.GraphicsWorldTransform;
}
else
{
objMatrix = colObj.WorldTransform;
}
wireColor = new Vector3(1.0f, 1.0f, 0.5f); //wants deactivation
if ((i & 1) == 1)
{
wireColor = new Vector3(0.0f, 0.0f, 1.0f);
}
//color differently for active, sleeping, wantsdeactivation states
if (colObj.ActivationState == ActivationState.Active)
{
if ((i & 1) == 1)
{
wireColor += new Vector3(1.0f, 0.0f, 0.0f);
}
else
{
wireColor += new Vector3(0.5f, 0.0f, 0.0f);
}
}
if (colObj.ActivationState == ActivationState.IslandSleeping)
{
if ((i & 1) == 1)
{
wireColor += new Vector3(0.0f, 1.0f, 0.0f);
}
else
{
wireColor += new Vector3(0.0f, 0.5f, 0.0f);
}
}
// draw box
objMatrix = XnaDevRu.BulletX.MathHelper.GetDisplayMatrix(objMatrix);
if (i == 0)
wireColor = Vector3.Zero;
DrawModel(objMatrix, wireColor, colObj);
}
}
base.Draw(gameTime);
}
private void DrawModel(Matrix modelTransform, Vector3 color, CollisionObject obj)
{
Model model = _modelBox;
Matrix scale = Matrix.Identity;
if (obj.CollisionShape is CylinderShape)
{
CylinderShape cylinderShape = (CylinderShape)obj.CollisionShape;
Vector3 halfExtent = cylinderShape.HalfExtents;
scale = Matrix.CreateScale(halfExtent.X + _collisionMargin, halfExtent.Y + _collisionMargin, halfExtent.Z / 2 + _collisionMargin * 3.5f) * Matrix.CreateRotationX((float)Math.PI / 2);
model = _modelCylinder;
}
else if (obj.CollisionShape is BoxShape)
{
BoxShape boxShape = (BoxShape)obj.CollisionShape;
Vector3 halfExtent = boxShape.HalfExtents;
scale = Matrix.CreateScale(2 * halfExtent.X, 2 * halfExtent.Y, 2 * halfExtent.Z);
model = _modelBox;
}
else if (obj.CollisionShape is SphereShape)
{
SphereShape sphereShape = (SphereShape)obj.CollisionShape;
float radius = sphereShape.Radius;
scale = Matrix.CreateScale(radius, radius, radius);
model = _modelSphere;
}
Matrix[] transforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(transforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
effect.AmbientLightColor = color;
effect.View = _camera.View;
effect.Projection = _camera.Projection;
effect.World = transforms[mesh.ParentBone.Index] * scale * modelTransform;
}
mesh.Draw();
}
}
private void shootBox(Vector3 destination)
{
if (_world != null)
{
float mass = 1f;
Matrix startTransform = Matrix.Identity;
Vector3 camPos = _camera.Position;
startTransform.Translation = camPos;
//CollisionShape boxShape = new SphereShape(1);
CollisionShape boxShape = new BoxShape(Vector3.One);
RigidBody body = CreateRigidBody(mass, startTransform, boxShape);
Vector3 linVel = new Vector3(destination.X - camPos.X, destination.Y - camPos.Y, destination.Z - camPos.Z);
linVel.Normalize();
linVel *= _shootBoxInitialSpeed;
//body.getWorldTransform().setOrigin(camPos);
//body.getWorldTransform().setRotation(btQuaternion(0, 0, 0, 1));
body.LinearVelocity = linVel;
body.AngularVelocity = Vector3.Zero;
}
}
private Vector3 getRayTo(int x, int y)
{
Vector3 nearSource = new Vector3(x, y, 0);
Vector3 farSource = new Vector3(x, y, 1);
Matrix world = Matrix.CreateTranslation(0, 0, 0);
Vector3 nearPoint = Graphics.GraphicsDevice.Viewport.Unproject(nearSource, Camera.Projection, Camera.View, world);
Vector3 farPoint = Graphics.GraphicsDevice.Viewport.Unproject(farSource, Camera.Projection, Camera.View, world);
Vector3 direction = farPoint - nearPoint;
//direction.Normalize();
return direction;
}
}
}

View File

@ -0,0 +1,31 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("XnaDevRu.BulletX.Demos")]
[assembly: AssemblyProduct("Bullet for XNA")]
[assembly: AssemblyDescription("BulletX Common Demo Code")]
[assembly: AssemblyCompany("XNADev.ru")]
[assembly: AssemblyCopyright("Copyright © 2007 XNADev.ru")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("49577e4d-b699-4933-972d-7734f73b02ba")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
[assembly: AssemblyVersion("1.0.149.21894")]

View File

@ -0,0 +1,115 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{2DF77065-B2FF-4DBB-96BB-A28E09A4A23A}</ProjectGuid>
<ProjectTypeGuids>{9F340DF3-2AED-4330-AC16-78AC2D9B4738};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>XnaDevRu.BulletX.Demos</RootNamespace>
<AssemblyName>XnaDevRu.BulletX.Demos</AssemblyName>
<XnaFrameworkVersion>v1.0</XnaFrameworkVersion>
<XnaPlatform>Windows</XnaPlatform>
<XNAGlobalContentPipelineAssemblies>Microsoft.Xna.Framework.Content.Pipeline.EffectImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.FBXImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.TextureImporter.dll;Microsoft.Xna.Framework.Content.Pipeline.XImporter.dll</XNAGlobalContentPipelineAssemblies>
<XNAProjectContentPipelineAssemblies>
</XNAProjectContentPipelineAssemblies>
<SignAssembly>false</SignAssembly>
<AssemblyOriginatorKeyFile>BulletXDemos.snk</AssemblyOriginatorKeyFile>
<DelaySign>true</DelaySign>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>..\..\..\..\Build\x86\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>..\..\..\..\Build\x86\Debug\XnaDevRu.BulletX.Demos.XML</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>..\..\..\..\Build\x86\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
<NoStdLib>true</NoStdLib>
<UseVSHostingProcess>false</UseVSHostingProcess>
<PlatformTarget>x86</PlatformTarget>
<DocumentationFile>..\..\..\..\Build\x86\Release\XnaDevRu.BulletX.Demos.XML</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Xna.Framework">
<Private>False</Private>
</Reference>
<Reference Include="Microsoft.Xna.Framework.Game">
<Private>False</Private>
</Reference>
<Reference Include="mscorlib">
<Private>False</Private>
</Reference>
<Reference Include="System">
<Private>False</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="DemoGame.cs">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>DemoGame</Name>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\..\XnaDevRu.Demos\Source\XnaDevRu.Demos\XnaDevRu.Demos.csproj">
<Project>{C54AF66D-0C55-4A84-9E7C-FC6346C78681}</Project>
<Name>XnaDevRu.Demos</Name>
</ProjectReference>
<ProjectReference Include="..\XnaDevRu.BulletX\XnaDevRu.BulletX.csproj">
<Project>{5BEE189F-47A1-42A8-A297-1960221BE20D}</Project>
<Name>XnaDevRu.BulletX</Name>
</ProjectReference>
</ItemGroup>
<ItemGroup>
<Content Include="..\..\..\SharedContent\Models\box.x">
<Link>Content\box.x</Link>
<XNAUseContentPipeline>true</XNAUseContentPipeline>
<Importer>XImporter</Importer>
<Processor>ModelProcessor</Processor>
<Name>box</Name>
</Content>
<Content Include="..\..\..\SharedContent\Models\cylinder.x">
<Link>Content\cylinder.x</Link>
<XNAUseContentPipeline>true</XNAUseContentPipeline>
<Importer>XImporter</Importer>
<Processor>ModelProcessor</Processor>
<Name>cylinder</Name>
</Content>
<Content Include="..\..\..\SharedContent\Models\sphere.x">
<Link>Content\sphere.x</Link>
<XNAUseContentPipeline>true</XNAUseContentPipeline>
<Importer>XImporter</Importer>
<Processor>ModelProcessor</Processor>
<Name>sphere</Name>
</Content>
</ItemGroup>
<ItemGroup>
<None Include="BulletXDemos.snk">
<XNAUseContentPipeline>false</XNAUseContentPipeline>
<Name>BulletXDemos</Name>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.ContentPipeline.targets" />
<Import Project="$(MSBuildExtensionsPath)\Microsoft\XNA\Game Studio Express\v1.0\Microsoft.Xna.Common.targets" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">
</Target>
<Target Name="AfterBuild">
</Target>
-->
</Project>

View File

@ -0,0 +1,68 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
namespace XnaDevRu.BulletX
{
internal static class BulletDebug
{
[Conditional("DEBUG")]
public static void Assert(Boolean condition)
{
//if (!condition)
//{
// Throw("No info available");
//}
Debug.Assert(condition);
}
[Conditional("DEBUG")]
public static void Assert(Boolean condition, String message)
{
//if (!condition)
//{
// Throw(message);
//}
Debug.Assert(condition, message);
}
[Conditional("DEBUG")]
public static void Assert(Boolean condition, String message, String detailMessage)
{
//if (!condition)
//{
// Throw(message);
//}
Debug.Assert(condition, message, detailMessage);
}
private static void Throw(String message)
{
String msg = String.Format("Assertion Error: {0}", message);
throw new BulletException(msg);
}
}
}

View File

@ -0,0 +1,623 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class AxisSweep3: OverlappingPairCache
{
Vector3 _worldAabbMin;
Vector3 _worldAabbMax;
Vector3 _quantize;
int _numHandles;
int _maxHandles;
Handle[] _handles;
Edge[][] _edges = new Edge[3][];
ushort _firstFreeHandle;
int _invalidPair;
public AxisSweep3(Vector3 worldAabbMin, Vector3 worldAabbMax, int maxHandles)
: base()
{
BulletDebug.Assert(maxHandles > 1 && maxHandles < 32767);
// init bounds
_worldAabbMin = worldAabbMin;
_worldAabbMax = worldAabbMax;
Vector3 aabbSize = _worldAabbMax - _worldAabbMin;
_quantize = new Vector3(65535.0f, 65535.0f, 65535.0f) / aabbSize;
// allocate handles buffer and put all handles on free list
_handles = new Handle[maxHandles];
for (int i = 0; i < maxHandles; i++)
_handles[i] = new Handle();
_maxHandles = maxHandles;
_numHandles = 0;
// handle 0 is reserved as the null index, and is also used as the sentinel
_firstFreeHandle = 1;
{
for (int i = _firstFreeHandle; i < maxHandles; i++)
{
_handles[i].NextFree = (ushort)(i + 1);
}
_handles[maxHandles - 1].NextFree = 0;
}
{
// allocate edge buffers
for (int i = 0; i < 3; i++)
{
_edges[i] = new Edge[maxHandles * 2];
for (int j = 0; j < maxHandles * 2; j++)
{
_edges[i][j] = new Edge();
}
}
}
//removed overlap management
// make boundary sentinels
_handles[0].ClientData = 0;
for (int axis = 0; axis < 3; axis++)
{
_handles[0].MinEdges[axis] = 0;
_handles[0].MaxEdges[axis] = 1;
_edges[axis][0].Position = 0;
_edges[axis][0].Handle = 0;
_edges[axis][1].Position = 0xffff;
_edges[axis][1].Handle = 0;
}
}
public ushort AddHandle(Vector3 aabbMin, Vector3 aabbMax, object owner, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
{
ushort[] min = new ushort[3], max = new ushort[3];
Quantize(out min, aabbMin, 0);
Quantize(out max, aabbMax, 1);
ushort handle = AllocateHandle();
Handle oHandle = GetHandle(handle);
oHandle.HandleID = handle;
oHandle.ClientData = owner;
oHandle.CollisionFilterGroup = collisionFilterGroup;
oHandle.CollisionFilterMask = collisionFilterMask;
int limit = _numHandles * 2;
// (Gluk )
// ( Inside )
for (int axis = 0; axis < 3; axis++)
{
_handles[0].MaxEdges[axis] += 2;
_edges[axis][limit + 1].Position = _edges[axis][limit - 1].Position;
_edges[axis][limit + 1].Handle = _edges[axis][limit - 1].Handle;
_edges[axis][limit - 1].Position = min[axis];
_edges[axis][limit - 1].Handle = handle;
_edges[axis][limit].Position = max[axis];
_edges[axis][limit].Handle = handle;
oHandle.MinEdges[axis] = (ushort)(limit - 1);
oHandle.MaxEdges[axis] = (ushort)limit;
}
SortMinDown(0, oHandle.MinEdges[0], false);
SortMaxDown(0, oHandle.MaxEdges[0], false);
SortMinDown(1, oHandle.MinEdges[1], false);
SortMaxDown(1, oHandle.MaxEdges[1], false);
SortMinDown(2, oHandle.MinEdges[2], true);
SortMaxDown(2, oHandle.MaxEdges[2], true);
return handle;
}
public void RemoveHandle(ushort handle)
{
Handle pHandle = GetHandle(handle);
//explicitly remove the pairs containing the proxy
//we could do it also in the sortMinUp (passing true)
//todo: compare performance
RemoveOverlappingPairsContainingProxy(pHandle);
// compute current limit of edge arrays
int limit = _numHandles * 2;
int axis;
for (axis = 0; axis < 3; axis++)
{
_handles[0].MaxEdges[axis] -= 2;
}
// remove the edges by sorting them up to the end of the list
for (axis = 0; axis < 3; axis++)
{
Edge[] pEdges = _edges[axis];
ushort max = pHandle.MaxEdges[axis];
pEdges[max].Position = 0xffff;
SortMaxUp(axis, max, false);
ushort i = pHandle.MinEdges[axis];
pEdges[i].Position = 0xffff;
SortMinUp(axis, i, false);
pEdges[limit - 1].Handle = 0;
pEdges[limit - 1].Position = 0xffff;
}
// free the handle
FreeHandle(handle);
}
public override void ProcessAllOverlappingPairs(IOverlapCallback callback)
{
OverlappingPairs.Sort(new Comparison<BroadphasePair>(BroadphasePair.ComparisonSort));
if (_invalidPair != 0)
OverlappingPairs.RemoveRange(OverlappingPairs.Count - _invalidPair, _invalidPair);
_invalidPair = 0;
BroadphasePair previousPair = new BroadphasePair();
previousPair.ProxyA = null;
previousPair.ProxyB = null;
previousPair.CollisionAlgorithm = null;
List<BroadphasePair> removal = new List<BroadphasePair>();
for (int i = 0; i < OverlappingPairs.Count; i++)
{
bool isDuplicate = (OverlappingPairs[i] == previousPair);
previousPair = OverlappingPairs[i];
bool needsRemoval;
if (!isDuplicate)
{
bool hasOverlap = TestOverlap(previousPair.ProxyA, previousPair.ProxyB);
if (hasOverlap)
{
needsRemoval = callback.ProcessOverlap(ref previousPair);
}
else
{
needsRemoval = true;
}
}
else
{
needsRemoval = true;
BulletDebug.Assert(previousPair.CollisionAlgorithm == null);
}
if (needsRemoval)
{
removal.Add(previousPair);
}
}
for (int i = 0; i < removal.Count; i++)
{
BroadphasePair pair = removal[i];
CleanOverlappingPair(ref pair);
pair.ProxyA = null;
pair.ProxyB = null;
_invalidPair++;
OverlappingPairCount--;
}
}
private bool TestOverlap(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
{
if (proxyA == null || proxyB == null)
return false;
Handle handleA = proxyA as Handle;
Handle handleB = proxyB as Handle;
for (int axis = 0; axis < 3; axis++)
{
if (handleA.MaxEdges[axis] < handleB.MinEdges[axis] ||
handleB.MaxEdges[axis] < handleA.MinEdges[axis])
{
return false;
}
}
return true;
}
private bool TestOverlap(int ignoreAxis, Handle pHandleA, Handle pHandleB)
{
for (int axis = 0; axis < 3; axis++)
{
if (axis != ignoreAxis)
{
if (pHandleA.MaxEdges[axis] < pHandleB.MinEdges[axis] ||
pHandleB.MaxEdges[axis] < pHandleA.MinEdges[axis])
{
return false;
}
}
}
return true;
}
private ushort AllocateHandle()
{
ushort handle = _firstFreeHandle;
_firstFreeHandle = GetHandle(handle).NextFree;
_numHandles++;
return handle;
}
private void FreeHandle(ushort handle)
{
BulletDebug.Assert(handle > 0 && handle < _maxHandles);
GetHandle(handle).NextFree = _firstFreeHandle;
_firstFreeHandle = handle;
_numHandles--;
}
private Handle GetHandle(ushort handle)
{
return _handles[handle];
}
private void UpdateHandle(ushort handle, Vector3 aabbMin, Vector3 aabbMax)
{
Handle pHandle = GetHandle(handle);
// quantize the new bounds
ushort[] min = new ushort[3];
ushort[] max = new ushort[3];
Quantize(out min, aabbMin, 0);
Quantize(out max, aabbMax, 1);
// update changed edges
for (int axis = 0; axis < 3; axis++)
{
ushort emin = pHandle.MinEdges[axis];
ushort emax = pHandle.MaxEdges[axis];
int dmin = (int)min[axis] - (int)_edges[axis][emin].Position;
int dmax = (int)max[axis] - (int)_edges[axis][emax].Position;
_edges[axis][emin].Position = min[axis];
_edges[axis][emax].Position = max[axis];
// expand (only adds overlaps)
if (dmin < 0)
SortMinDown(axis, emin, true);
if (dmax > 0)
SortMaxUp(axis, emax, true);
// shrink (only removes overlaps)
if (dmin > 0)
SortMinUp(axis, emin, true);
if (dmax < 0)
SortMaxDown(axis, emax, true);
}
}
private void Quantize(out ushort[] result, Vector3 point, int isMax)
{
Vector3 clampedPoint = new Vector3(
point.X,
point.Y,
point.Z
);
MathHelper.SetMax(ref clampedPoint, _worldAabbMin);
MathHelper.SetMin(ref clampedPoint, _worldAabbMax);
Vector3 v = (clampedPoint - _worldAabbMin) * _quantize;
result = new ushort[3];
result[0] = (ushort)(((int)v.X & 0xfffe) | isMax);
result[1] = (ushort)(((int)v.Y & 0xfffe) | isMax);
result[2] = (ushort)(((int)v.Z & 0xfffe) | isMax);
}
private void SortMinDown(int axis, ushort edge, bool updateOverlaps)
{
Edge pEdge = _edges[axis][edge];
Edge pPrev = _edges[axis][edge - 1];
Handle pHandleEdge = GetHandle(pEdge.Handle);
while (pEdge.Position < pPrev.Position)
{
Handle pHandlePrev = GetHandle(pPrev.Handle);
if (pPrev.IsMax())
{
// if previous edge is a maximum check the bounds and add an overlap if necessary
if (updateOverlaps && TestOverlap(axis, pHandleEdge, pHandlePrev))
{
AddOverlappingPair(pHandleEdge, pHandlePrev);
}
// update edge reference in other handle
pHandlePrev.MaxEdges[axis]++;
}
else
pHandlePrev.MinEdges[axis]++;
pHandleEdge.MinEdges[axis]--;
// swap the edges
pEdge.Swap(ref pPrev);
// decrement
edge--;
pEdge = _edges[axis][edge];
pPrev = _edges[axis][edge - 1];
}
}
private void SortMinUp(int axis, ushort edge, bool updateOverlaps)
{
Edge pEdge = _edges[axis][edge];
Edge pNext = _edges[axis][edge + 1];
Handle pHandleEdge = GetHandle(pEdge.Handle);
while ((pNext.Handle != 0) && (pEdge.Position >= pNext.Position))
{
Handle pHandleNext = GetHandle(pNext.Handle);
if (pNext.IsMax())
{
// if next edge is maximum remove any overlap between the two handles
if (updateOverlaps)
{
//Handle handle0 = GetHandle(pEdge.Handle);
//Handle handle1 = GetHandle(pNext.Handle);
//BroadphasePair tmpPair = new BroadphasePair(handle0, handle1);
//RemoveOverlappingPair(tmpPair);
}
// update edge reference in other handle
pHandleNext.MaxEdges[axis]--;
}
else
pHandleNext.MinEdges[axis]--;
pHandleEdge.MinEdges[axis]++;
// swap the edges
pEdge.Swap(ref pNext);
// increment
edge++;
pEdge = _edges[axis][edge];
pNext = _edges[axis][edge + 1];
}
}
private void SortMaxDown(int axis, ushort edge, bool updateOverlaps)
{
Edge pEdge = _edges[axis][edge];
Edge pPrev = _edges[axis][edge - 1];
Handle pHandleEdge = GetHandle(pEdge.Handle);
while (pEdge.Position < pPrev.Position)
{
Handle pHandlePrev = GetHandle(pPrev.Handle);
if (!pPrev.IsMax())
{
// if previous edge was a minimum remove any overlap between the two handles
if (updateOverlaps)
{
//this is done during the overlappingpairarray iteration/narrowphase collision
//Handle handle0 = GetHandle(pEdge.Handle);
//Handle handle1 = GetHandle(pPrev.Handle);
//BroadphasePair pair = FindPair(handle0, handle1);
//if (pair != null)
//{
// RemoveOverlappingPair(pair);
//}
}
// update edge reference in other handle
pHandlePrev.MinEdges[axis]++; ;
}
else
pHandlePrev.MaxEdges[axis]++;
pHandleEdge.MaxEdges[axis]--;
// swap the edges
pEdge.Swap(ref pPrev);
// decrement
edge--;
pEdge = _edges[axis][edge];
pPrev = _edges[axis][edge - 1];
}
}
private void SortMaxUp(int axis, ushort edge, bool updateOverlaps)
{
Edge pEdge = _edges[axis][edge];
Edge pNext = _edges[axis][edge + 1];
Handle pHandleEdge = GetHandle(pEdge.Handle);
while ((pNext.Handle!=0) && (pEdge.Position >= pNext.Position))
{
Handle pHandleNext = GetHandle(pNext.Handle);
if (!pNext.IsMax())
{
// if next edge is a minimum check the bounds and add an overlap if necessary
if (updateOverlaps && TestOverlap(axis, pHandleEdge, pHandleNext))
{
Handle handle0 = GetHandle(pEdge.Handle);
Handle handle1 = GetHandle(pNext.Handle);
AddOverlappingPair(handle0, handle1);
}
// update edge reference in other handle
pHandleNext.MinEdges[axis]--;
}
else
pHandleNext.MaxEdges[axis]--;
pHandleEdge.MaxEdges[axis]++;
// swap the edges
pEdge.Swap(ref pNext);
// increment
edge++;
pEdge = _edges[axis][edge];
pNext = _edges[axis][edge + 1];
}
}
#region Abstract
public override void RefreshOverlappingPairs()
{
}
public override BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
{
ushort handleId = AddHandle(min, max, userData, collisionFilterGroup, collisionFilterMask);
Handle handle = GetHandle(handleId);
return handle;
}
public override void DestroyProxy(BroadphaseProxy proxy)
{
Handle handle = proxy as Handle;
RemoveHandle(handle.HandleID);
}
public override void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax)
{
Handle handle = proxy as Handle;
UpdateHandle(handle.HandleID, aabbMin, aabbMax);
}
#endregion
}
public class Edge
{
ushort position;
ushort handle;
public ushort Position
{
get { return position; }
set { position = value; }
}
public ushort Handle
{
get { return handle; }
set { handle = value; }
}
public bool IsMax()
{
return (position & (ushort)1) == 1;
}
public void Swap(ref Edge e)
{
ushort tmpPosition = this.position;
ushort tmpHandle = this.handle;
this.position = e.position;
this.handle = e.handle;
e.position = tmpPosition;
e.handle = tmpHandle;
}
}
public class Handle: BroadphaseProxy
{
ushort[] minEdges, maxEdges;
ushort pad;
ushort handleID;
public ushort[] MinEdges
{
get { return minEdges; }
set { minEdges = value; }
}
public ushort[] MaxEdges
{
get { return maxEdges; }
set { maxEdges = value; }
}
public ushort HandleID
{
get { return handleID; }
set { handleID = value; }
}
public ushort Pad
{
get { return pad; }
set { pad = value; }
}
public ushort NextFree
{
get { return minEdges[0]; }
set { minEdges[0] = value;}
}
public Handle()
{
minEdges = new ushort[3];
maxEdges = new ushort[3];
}
}
}

View File

@ -0,0 +1,68 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
/// Dispatcher uses these types
/// IMPORTANT NOTE:The types are ordered polyhedral, implicit convex and concave
/// to facilitate type checking
public enum BroadphaseNativeTypes
{
// polyhedral convex shapes
Box,
Triangle,
Tetrahedral,
ConvexTriangleMesh,
ConvexHull,
//implicit convex shapes
ImplicitConvexShapes,
Sphere,
MultiSphere,
Capsule,
Cone,
Convex,
Cylinder,
MinkowskiSum,
MinkowskiDifference,
//concave shapes
ConcaveShapesStart,
//keep all the convex shapetype below here, for the check IsConvexShape in broadphase proxy!
TriangleMesh,
//used for demo integration FAST/Swift collision library and Bullet
FastConcaveMesh,
//terrain
Terrain,
//Used for GIMPACT Trimesh integration
Gimpact,
Empty,
StaticPlane,
ConcaveShapesEnd,
Compound,
MaxBroadphaseCollisionTypes,
}
}

View File

@ -0,0 +1,113 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public class BroadphasePair
{
private BroadphaseProxy _proxyA;
private BroadphaseProxy _proxyB;
private CollisionAlgorithm _algorithm;
private object _userInfo;
public BroadphasePair()
{
}
public BroadphasePair(BroadphasePair other)
{
_proxyA = other._proxyA;
_proxyB = other._proxyB;
_algorithm = other._algorithm;
_userInfo = null;
}
public BroadphasePair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
{
_proxyA = proxyA;
_proxyB = proxyB;
_algorithm = null;
_userInfo = null;
}
public BroadphaseProxy ProxyA { get { return _proxyA; } set { _proxyA = value; } }
public BroadphaseProxy ProxyB { get { return _proxyB; } set { _proxyB = value; } }
public CollisionAlgorithm CollisionAlgorithm { get { return _algorithm; } set { _algorithm = value; } }
public object UserInfo { get { return _userInfo; } set { _userInfo = value; } }
public override int GetHashCode()
{
return _proxyA.GetHashCode() ^ _proxyB.GetHashCode();
}
public override bool Equals(object obj)
{
if (obj is BroadphasePair)
return this == (BroadphasePair)obj;
return false;
}
public static int ComparisonSort(BroadphasePair a, BroadphasePair b)
{
int aAId = a.ProxyA != null ? a.ProxyA.ComparisonID : -1;
int aBId = a.ProxyB != null ? a.ProxyB.ComparisonID : -1;
int aCId = a.CollisionAlgorithm != null ? a.CollisionAlgorithm.ComparisonID : -1;
int bAId = b.ProxyA != null ? b.ProxyA.ComparisonID : -1;
int bBId = b.ProxyB != null ? b.ProxyB.ComparisonID : -1;
int bCId = b.CollisionAlgorithm != null ? b.CollisionAlgorithm.ComparisonID : -1;
if (aAId > bAId ||
(a.ProxyA == b.ProxyA && aBId > bBId) ||
(a.ProxyA == b.ProxyA && a.ProxyB == b.ProxyB && aCId > bCId))
return -1;
else
return 1;
}
public static bool operator ==(BroadphasePair a, BroadphasePair b)
{
if (object.Equals(a, null) && object.Equals(b, null))
return true;
if (object.Equals(a, null) || object.Equals(b, null))
return false;
return (a.ProxyA == b.ProxyA) && (a.ProxyB == b.ProxyB);
}
public static bool operator !=(BroadphasePair a, BroadphasePair b)
{
if (object.Equals(a, null) && object.Equals(b, null))
return true;
if (object.Equals(a, null) || object.Equals(b, null))
return false;
return (a.ProxyA != b.ProxyA) || (a.ProxyB != b.ProxyB);
}
}
}

View File

@ -0,0 +1,91 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public class BroadphaseProxy
{
//Usually the client CollisionObject or Rigidbody class
private object _clientObject;
private CollisionFilterGroups _collisionFilterGroup;
private CollisionFilterGroups _collisionFilterMask;
private readonly int _comparisonID;
private static int _globalCount = 0;
public BroadphaseProxy()
{
_comparisonID = _globalCount++;
}
public BroadphaseProxy(object userData, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask)
: this()
{
_clientObject = userData;
_collisionFilterGroup = collisionFilterGroup;
_collisionFilterMask = collisionFilterMask;
}
public object ClientData { get { return _clientObject; } set { _clientObject = value; } }
public CollisionFilterGroups CollisionFilterGroup { get { return _collisionFilterGroup; } set { _collisionFilterGroup = value; } }
public CollisionFilterGroups CollisionFilterMask { get { return _collisionFilterMask; } set { _collisionFilterMask = value; } }
internal int ComparisonID { get { return _comparisonID; } }
public static bool IsPolyhedral(BroadphaseNativeTypes proxyType)
{
return (proxyType < BroadphaseNativeTypes.ImplicitConvexShapes);
}
public static bool IsConvex(BroadphaseNativeTypes proxyType)
{
return (proxyType < BroadphaseNativeTypes.ConcaveShapesStart);
}
public static bool IsConcave(BroadphaseNativeTypes proxyType)
{
return ((proxyType > BroadphaseNativeTypes.ConcaveShapesStart) &&
(proxyType < BroadphaseNativeTypes.ConcaveShapesEnd));
}
public static bool IsCompound(BroadphaseNativeTypes proxyType)
{
return (proxyType == BroadphaseNativeTypes.Compound);
}
public static bool IsInfinite(BroadphaseNativeTypes proxyType)
{
return (proxyType == BroadphaseNativeTypes.StaticPlane);
}
//optional filtering to cull potential collisions
public enum CollisionFilterGroups
{
Default = 1,
Static = 2,
Kinematic = 4,
Debris = 8,
Sensor = 16,
All = Default | Static | Kinematic | Debris | Sensor,
}
}
}

View File

@ -0,0 +1,51 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
/// <summary>
/// CollisionAlgorithm is an collision interface that is compatible with the Broadphase and Dispatcher.
/// It is persistent over frames
/// </summary>
public abstract class CollisionAlgorithm
{
private IDispatcher _dispatcher;
private readonly int _comparisonID = 0;
private static int _globalCount = 0;
public CollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
{
_comparisonID = _globalCount++;
_dispatcher = collisionAlgorithmConstructionInfo.Dispatcher;
}
protected IDispatcher Dispatcher { get { return _dispatcher; } set { _dispatcher = value; } }
internal int ComparisonID { get { return _comparisonID; } }
public abstract void ProcessCollision(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut);
public abstract float CalculateTimeOfImpact(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut);
}
}

View File

@ -0,0 +1,42 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public struct CollisionAlgorithmConstructionInfo
{
private IDispatcher _dispatcher;
private PersistentManifold _manifold;
public CollisionAlgorithmConstructionInfo(IDispatcher dispatcher)
{
_dispatcher = dispatcher;
_manifold = null;
}
public IDispatcher Dispatcher { get { return _dispatcher; } set { _dispatcher = value; } }
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
}
}

View File

@ -0,0 +1,54 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public enum DispatchFunction
{
Discrete = 1,
Continuous,
}
public class DispatcherInfo
{
private float _timeStep;
private int _stepCount;
private DispatchFunction _dispatchFunc = DispatchFunction.Discrete;
private float _timeOfImpact = 1;
private bool _useContinuous;
private bool _enableSatConvex;
private bool _enableSpu;
private IDebugDraw _debugDraw;
public float TimeStep { get { return _timeStep; } set { _timeStep = value; } }
public int StepCount { get { return _stepCount; } set { _stepCount = value; } }
public DispatchFunction DispatchFunction { get { return _dispatchFunc; } set { _dispatchFunc = value; } }
public float TimeOfImpact { get { return _timeOfImpact; } set { _timeOfImpact = value; } }
public bool UseContinuous { get { return _useContinuous; } set { _useContinuous = value; } }
public bool EnableSatConvex { get { return _enableSatConvex; } set { _enableSatConvex = value; } }
public bool enableSpu { get { return _enableSpu; } set { _enableSpu = value; } }
public IDebugDraw DebugDraw { get { return _debugDraw; } set { _debugDraw = value; } }
}
}

View File

@ -0,0 +1,36 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public interface IBroadphase
{
BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask);
void DestroyProxy(BroadphaseProxy proxy);
void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax);
void CleanProxyFromPairs(BroadphaseProxy proxy);
}
}

View File

@ -0,0 +1,42 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public interface IDispatcher
{
CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold);
CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB);
PersistentManifold GetNewManifold(object bodyA, object bodyB);
void ReleaseManifold(PersistentManifold manifold);
void ClearManifold(PersistentManifold manifold);
bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB);
bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB);
void DispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo);
PersistentManifold GetManifoldByIndex(int index);
int ManifoldCount { get; }
}
}

View File

@ -0,0 +1,33 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public interface IOverlapCallback
{
//return true for deletion of the pair
bool ProcessOverlap(ref BroadphasePair pair);
}
}

View File

@ -0,0 +1,159 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public abstract class OverlappingPairCache : IBroadphase
{
private static int _overlappingPairCount = 0;
private List<BroadphasePair> _overlappingPairs = new List<BroadphasePair>();
//during the dispatch, check that user doesn't destroy/create proxy
private bool _blockedForChanges;
public List<BroadphasePair> OverlappingPairs { get { return _overlappingPairs; } set { _overlappingPairs = value; } }
public bool BlockedForChanges { get { return _blockedForChanges; } set { _blockedForChanges = value; } }
public static int OverlappingPairCount { get { return _overlappingPairCount; } set { _overlappingPairCount = value; } }
public void RemoveOverlappingPair(BroadphasePair pair)
{
if (!_overlappingPairs.Contains(pair))
return;
CleanOverlappingPair(ref pair);
_overlappingPairs.Remove(pair);
}
public void AddOverlappingPair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
{
//don't add overlap with own
bool test = proxyA != proxyB;
BulletDebug.Assert(proxyA != proxyB);
if (!NeedsBroadphaseCollision(proxyA, proxyB))
return;
BroadphasePair pair = new BroadphasePair(proxyA, proxyB);
_overlappingPairs.Add(pair);
_overlappingPairCount++;
}
//this FindPair becomes really slow. Either sort the list to speedup the query, or
//use a different solution. It is mainly used for Removing overlapping pairs. Removal could be delayed.
//we could keep a linked list in each proxy, and store pair in one of the proxies (with lowest memory address)
//Also we can use a 2D bitmap, which can be useful for a future GPU implementation
public BroadphasePair FindPair(BroadphaseProxy proxyA, BroadphaseProxy proxyB)
{
if (!NeedsBroadphaseCollision(proxyA, proxyB))
return null;
BroadphasePair pair = new BroadphasePair(proxyA, proxyB);
for (int i = 0; i < _overlappingPairs.Count; i++)
{
if (_overlappingPairs[i] == pair)
{
return _overlappingPairs[i];
}
}
return null;
}
public void CleanProxyFromPairs(BroadphaseProxy proxy)
{
for (int i = 0; i < _overlappingPairs.Count; i++)
{
BroadphasePair pair = _overlappingPairs[i];
if (pair.ProxyA == proxy ||
pair.ProxyB == proxy)
{
CleanOverlappingPair(ref pair);
_overlappingPairs[i] = pair;
}
}
}
public void RemoveOverlappingPairsContainingProxy(BroadphaseProxy proxy)
{
for (int i = _overlappingPairs.Count - 1; i >= 0; i--)
{
BroadphasePair pair = _overlappingPairs[i];
if (pair.ProxyA == proxy ||
pair.ProxyB == proxy)
{
RemoveOverlappingPair(pair);
i++;
}
}
}
public bool NeedsBroadphaseCollision(BroadphaseProxy proxy0, BroadphaseProxy proxy1)
{
bool collides = (proxy0.CollisionFilterGroup & proxy1.CollisionFilterMask) != 0;
collides = collides && ((proxy1.CollisionFilterGroup & proxy0.CollisionFilterMask) != 0);
return collides;
}
public virtual void ProcessAllOverlappingPairs(IOverlapCallback callback)
{
List<BroadphasePair> deleting = new List<BroadphasePair>();
for (int i = 0; i < _overlappingPairs.Count; i++)
{
BroadphasePair p = _overlappingPairs[i];
if (callback.ProcessOverlap(ref p))
{
CleanOverlappingPair(ref p);
deleting.Add(p);
_overlappingPairCount--;
}
}
for (int i = 0; i < deleting.Count; i++)
_overlappingPairs.Remove(deleting[i]);
}
public void CleanOverlappingPair(ref BroadphasePair pair)
{
if (pair.CollisionAlgorithm != null)
{
if (pair.CollisionAlgorithm is IDisposable)
(pair.CollisionAlgorithm as IDisposable).Dispose();
pair.CollisionAlgorithm = null;
}
}
public abstract void RefreshOverlappingPairs();
#region IBroadphase Members
public abstract BroadphaseProxy CreateProxy(Microsoft.Xna.Framework.Vector3 min, Microsoft.Xna.Framework.Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask);
public abstract void DestroyProxy(BroadphaseProxy proxy);
public abstract void SetAabb(BroadphaseProxy proxy, Microsoft.Xna.Framework.Vector3 aabbMin, Microsoft.Xna.Framework.Vector3 aabbMax);
#endregion
}
}

View File

@ -0,0 +1,128 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class SimpleBroadphase : OverlappingPairCache
{
private int _maxProxies;
private List<SimpleBroadphaseProxy> _proxies = new List<SimpleBroadphaseProxy>();
public SimpleBroadphase()
: this(16384) { }
public SimpleBroadphase(int maxProxies)
: base()
{
_maxProxies = maxProxies;
}
public override BroadphaseProxy CreateProxy(Vector3 min, Vector3 max, BroadphaseNativeTypes shapeType, object userData, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
{
if (_proxies.Count >= _maxProxies)
{
BulletDebug.Assert(false);
return null; //should never happen, but don't let the game crash ;-)
}
BulletDebug.Assert(min.X <= max.X && min.Y <= max.Y && min.Z <= max.Z);
SimpleBroadphaseProxy proxy = new SimpleBroadphaseProxy(min, max, shapeType, userData, collisionFilterGroup, collisionFilterMask);
_proxies.Add(proxy);
return proxy;
}
public override void DestroyProxy(BroadphaseProxy proxy)
{
RemoveOverlappingPairsContainingProxy(proxy);
_proxies.Remove(proxy as SimpleBroadphaseProxy);
}
public override void SetAabb(BroadphaseProxy proxy, Vector3 aabbMin, Vector3 aabbMax)
{
SimpleBroadphaseProxy simpleProxy = GetSimpleProxyFromProxy(proxy);
simpleProxy.Minimum = aabbMin;
simpleProxy.Maximum = aabbMax;
}
private SimpleBroadphaseProxy GetSimpleProxyFromProxy(BroadphaseProxy proxy)
{
return proxy as SimpleBroadphaseProxy;
}
public override void RefreshOverlappingPairs()
{
for (int i = 0; i < _proxies.Count; i++)
{
SimpleBroadphaseProxy proxyA = _proxies[i];
for (int j = i + 1; j < _proxies.Count; j++)
{
SimpleBroadphaseProxy proxyB = _proxies[j];
if (AabbOverlap(proxyA, proxyB))
{
if (FindPair(proxyA, proxyB) == null)
{
AddOverlappingPair(proxyA, proxyB);
}
}
}
}
CheckOverlapCallback check = new CheckOverlapCallback();
ProcessAllOverlappingPairs(check);
}
public static bool AabbOverlap(SimpleBroadphaseProxy proxyA, SimpleBroadphaseProxy proxyB)
{
return proxyA.Minimum.X <= proxyB.Maximum.X && proxyB.Minimum.X <= proxyA.Maximum.X &&
proxyA.Minimum.Y <= proxyB.Maximum.Y && proxyB.Minimum.Y <= proxyA.Maximum.Y &&
proxyA.Minimum.Z <= proxyB.Maximum.Z && proxyB.Minimum.Z <= proxyA.Maximum.Z;
}
private void Validate()
{
for (int i = 0; i < _proxies.Count; i++)
{
for (int j = i + 1; j < _proxies.Count; j++)
{
if (_proxies[i] == _proxies[j])
throw new BulletException();
}
}
}
}
public class CheckOverlapCallback : IOverlapCallback
{
public bool ProcessOverlap(ref BroadphasePair pair)
{
return (!SimpleBroadphase.AabbOverlap(pair.ProxyA as SimpleBroadphaseProxy, pair.ProxyB as SimpleBroadphaseProxy));
}
}
}

View File

@ -0,0 +1,46 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class SimpleBroadphaseProxy : BroadphaseProxy
{
private Vector3 _min;
private Vector3 _max;
public SimpleBroadphaseProxy() { }
public SimpleBroadphaseProxy(Vector3 minPoint, Vector3 maxPoint, BroadphaseNativeTypes shapeType, object userData, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask)
: base(userData, collisionFilterGroup, collisionFilterMask)
{
_min = minPoint;
_max = maxPoint;
}
public Vector3 Minimum { get { return _min; } set { _min = value; } }
public Vector3 Maximum { get { return _max; } set { _max = value; } }
}
}

View File

@ -0,0 +1,59 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
internal class BridgeTriangleRaycastCallback : TriangleRaycastCallback
{
CollisionWorld.RayResultCallback _resultCallback;
CollisionObject _collisionObject;
TriangleMeshShape _triangleMesh;
public BridgeTriangleRaycastCallback(Vector3 from, Vector3 to,
CollisionWorld.RayResultCallback resultCallback, CollisionObject collisionObject, TriangleMeshShape triangleMesh)
: base(from, to)
{
_resultCallback = resultCallback;
_collisionObject = collisionObject;
_triangleMesh = triangleMesh;
}
public override float ReportHit(Vector3 hitNormalLocal, float hitFraction, int partId, int triangleIndex)
{
CollisionWorld.LocalShapeInfo shapeInfo = new CollisionWorld.LocalShapeInfo();
shapeInfo.ShapePart = partId;
shapeInfo.TriangleIndex = triangleIndex;
CollisionWorld.LocalRayResult rayResult = new CollisionWorld.LocalRayResult
(_collisionObject,
shapeInfo,
hitNormalLocal,
hitFraction);
return _resultCallback.AddSingleResult(rayResult);
}
}
}

View File

@ -0,0 +1,40 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CollisionAlgorithmCreateFunction
{
private bool _swapped;
public bool IsSwapped { get { return _swapped; } set { _swapped = value; } }
public virtual CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo ci, CollisionObject body0, CollisionObject body1)
{
return null;
}
}
}

View File

@ -0,0 +1,280 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public delegate void NearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo);
public class CollisionDispatcher : IDispatcher
{
private List<PersistentManifold> _manifolds = new List<PersistentManifold>();
//private bool _useIslands;
private NearCallback _nearCallback;
//private ManifoldResult _defaultManifoldResult;
private CollisionAlgorithmCreateFunction[,] _doubleDispatch = new CollisionAlgorithmCreateFunction[(int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes, (int)BroadphaseNativeTypes.MaxBroadphaseCollisionTypes];
//default CreationFunctions, filling the m_doubleDispatch table
private CollisionAlgorithmCreateFunction _convexConvexCreateFunc;
private CollisionAlgorithmCreateFunction _convexConcaveCreateFunc;
private CollisionAlgorithmCreateFunction _swappedConvexConcaveCreateFunc;
private CollisionAlgorithmCreateFunction _compoundCreateFunc;
private CollisionAlgorithmCreateFunction _swappedCompoundCreateFunc;
private CollisionAlgorithmCreateFunction _emptyCreateFunc;
private int _count;
private static int _manifoldCount = 0;
public CollisionDispatcher()
{
NearCallback = DefaultNearCallback;
//_useIslands = true;
//default CreationFunctions, filling the m_doubleDispatch table
_convexConvexCreateFunc = new ConvexConvexAlgorithm.CreateFunc();
_convexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.CreateFunc();
_swappedConvexConcaveCreateFunc = new ConvexConcaveCollisionAlgorithm.SwappedCreateFunc();
_compoundCreateFunc = new CompoundCollisionAlgorithm.CreateFunc();
_swappedCompoundCreateFunc = new CompoundCollisionAlgorithm.SwappedCreateFunc();
_emptyCreateFunc = new EmptyAlgorithm.CreateFunc();
for (BroadphaseNativeTypes i = BroadphaseNativeTypes.Box; i < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; i++)
{
for (BroadphaseNativeTypes j = BroadphaseNativeTypes.Box; j < BroadphaseNativeTypes.MaxBroadphaseCollisionTypes; j++)
{
_doubleDispatch[(int)i, (int)j] = FindCreateFunction(i, j);
if (_doubleDispatch[(int)i, (int)j] == null)
throw new BulletException();
}
}
}
public int Count { get { return _count; } set { _count = value; } }
public int ManifoldCount { get { return _manifolds.Count; } }
public List<PersistentManifold> Manifolds { get { return _manifolds; } }
public static int GlobalManifoldCount { get { return _manifoldCount; } set { _manifoldCount = value; } }
public PersistentManifold GetManifoldByIndex(int index)
{
return _manifolds[index];
}
//registerCollisionCreateFunc allows registration of custom/alternative collision create functions
public void RegisterCollisionCreateFunc(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB, CollisionAlgorithmCreateFunction createFunc)
{
_doubleDispatch[(int)proxyTypeA, (int)proxyTypeB] = createFunc;
}
public virtual PersistentManifold GetNewManifold(object bodyA, object bodyB)
{
_manifoldCount++;
CollisionObject body0 = bodyA as CollisionObject;
CollisionObject body1 = bodyB as CollisionObject;
PersistentManifold manifold = new PersistentManifold(body0, body1);
_manifolds.Add(manifold);
return manifold;
}
public virtual void ReleaseManifold(PersistentManifold manifold)
{
_manifoldCount--;
ClearManifold(manifold);
_manifolds.Remove(manifold);
}
public virtual void ClearManifold(PersistentManifold manifold)
{
manifold.ClearManifold();
}
public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB)
{
return FindAlgorithm(bodyA, bodyB, null);
}
public CollisionAlgorithm FindAlgorithm(CollisionObject bodyA, CollisionObject bodyB, PersistentManifold sharedManifold)
{
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
collisionAlgorithmConstructionInfo.Dispatcher = this;
collisionAlgorithmConstructionInfo.Manifold = sharedManifold;
CollisionAlgorithm collisionAlgorithm = _doubleDispatch[(int)bodyA.CollisionShape.ShapeType, (int)bodyB.CollisionShape.ShapeType].CreateCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB);
return collisionAlgorithm;
}
/*public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1)
{
return internalFindAlgorithm(body0, body1, null);
}
public CollisionAlgorithm internalFindAlgorithm(CollisionObject body0, CollisionObject body1, PersistentManifold sharedManifold)
{
m_count++;
CollisionAlgorithmConstructionInfo ci = new CollisionAlgorithmConstructionInfo();
ci.m_dispatcher = this;
if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConvex())
{
return new ConvexConvexAlgorithm(sharedManifold, ci, body0, body1);
}
if (body0.getCollisionShape().isConvex() && body1.getCollisionShape().isConcave())
{
return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, false);
}
if (body1.getCollisionShape().isConvex() && body0.getCollisionShape().isConcave())
{
return new ConvexConcaveCollisionAlgorithm(ci, body0, body1, true);
}
if (body0.getCollisionShape().isCompound())
{
return new CompoundCollisionAlgorithm(ci, body0, body1, false);
}
else
{
if (body1.getCollisionShape().isCompound())
{
return new CompoundCollisionAlgorithm(ci, body0, body1, true);
}
}
//failed to find an algorithm
return new EmptyAlgorithm(ci);
}*/
public virtual bool NeedsCollision(CollisionObject bodyA, CollisionObject bodyB)
{
if (bodyA == null || bodyB == null)
throw new BulletException();
bool needsCollision = true;
//broadphase filtering already deals with this
/*if ((body0.isStaticObject() || body0.isKinematicObject()) &&
(body1.isStaticObject() || body1.isKinematicObject()))
{
printf("warning btCollisionDispatcher::needsCollision: static-static collision!\n");
}*/
if ((!bodyA.IsActive) && (!bodyB.IsActive))
needsCollision = false;
return needsCollision;
}
public virtual bool NeedsResponse(CollisionObject bodyA, CollisionObject bodyB)
{
//here you can do filtering
bool hasResponse = bodyA.HasContactResponse && bodyB.HasContactResponse;
hasResponse = hasResponse && (!bodyA.IsStaticOrKinematicObject || !bodyB.IsStaticOrKinematicObject);
return hasResponse;
}
public virtual void DispatchAllCollisionPairs(OverlappingPairCache pairCache, DispatcherInfo dispatchInfo)
{
CollisionPairCallback collisionCallback = new CollisionPairCallback(dispatchInfo, this);
pairCache.ProcessAllOverlappingPairs(collisionCallback);
}
private CollisionAlgorithmCreateFunction FindCreateFunction(BroadphaseNativeTypes proxyTypeA, BroadphaseNativeTypes proxyTypeB)
{
if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConvex(proxyTypeB))
{
return _convexConvexCreateFunc;
}
if (BroadphaseProxy.IsConvex(proxyTypeA) && BroadphaseProxy.IsConcave(proxyTypeB))
{
return _convexConcaveCreateFunc;
}
if (BroadphaseProxy.IsConvex(proxyTypeB) && BroadphaseProxy.IsConcave(proxyTypeA))
{
return _swappedConvexConcaveCreateFunc;
}
if (BroadphaseProxy.IsCompound(proxyTypeA))
{
return _compoundCreateFunc;
}
else
{
if (BroadphaseProxy.IsCompound(proxyTypeB))
{
return _swappedCompoundCreateFunc;
}
}
//failed to find an algorithm
return _emptyCreateFunc;
}
public NearCallback NearCallback { get { return _nearCallback; } set { _nearCallback = value; } }
//by default, Bullet will use this near callback
public static void DefaultNearCallback(ref BroadphasePair collisionPair, CollisionDispatcher dispatcher, DispatcherInfo dispatchInfo)
{
CollisionObject collisionObjectA = collisionPair.ProxyA.ClientData as CollisionObject;
CollisionObject collisionObjectB = collisionPair.ProxyB.ClientData as CollisionObject;
if (dispatcher.NeedsCollision(collisionObjectA, collisionObjectB))
{
//dispatcher will keep algorithms persistent in the collision pair
if (collisionPair.CollisionAlgorithm == null)
{
collisionPair.CollisionAlgorithm = dispatcher.FindAlgorithm(collisionObjectA, collisionObjectB);
}
if (collisionPair.CollisionAlgorithm != null)
{
ManifoldResult contactPointResult = new ManifoldResult(collisionObjectA, collisionObjectB);
if (dispatchInfo.DispatchFunction == DispatchFunction.Discrete)
{
//discrete collision detection query
collisionPair.CollisionAlgorithm.ProcessCollision(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
}
else
{
//continuous collision detection query, time of impact (toi)
float timeOfImpact = collisionPair.CollisionAlgorithm.CalculateTimeOfImpact(collisionObjectA, collisionObjectB, dispatchInfo, contactPointResult);
if (dispatchInfo.TimeOfImpact > timeOfImpact)
dispatchInfo.TimeOfImpact = timeOfImpact;
}
}
}
}
}
}

View File

@ -0,0 +1,163 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public enum ActivationState
{
Nothing = 0,
Active,
IslandSleeping,
WantsDeactivation,
DisableDeactivation,
DisableSimulation,
}
public enum CollisionOptions
{
StaticObject = 1,
KinematicObject = 2,
NoContactResponse = 4,
CustomMaterialCallback = 8,//this allows per-triangle material (friction/restitution)
}
/// <summary>
/// btCollisionObject can be used to manage collision detection objects.
/// btCollisionObject maintains all information that is needed for a collision detection: Shape, Transform and AABB proxy.
/// They can be added to the btCollisionWorld.
/// </summary>
public class CollisionObject
{
protected Matrix _worldTransform;
private BroadphaseProxy _broadphase;
private CollisionShape _collisionShape;
//m_interpolationWorldTransform is used for CCD and interpolation
//it can be either previous or future (predicted) transform
private Matrix _interpolationWorldTransform;
private CollisionOptions _collisionFlags;
private int _islandTag;
private ActivationState _activationState;
private float _deactivationTime;
private float _friction;
private float _restitution;
//users can point to their objects, m_userPointer is not used by Bullet
private object _userData;
//m_internalOwner one is used by optional Bullet high level interface
private object _internalOwner;
//time of impact calculation
private float _hitFraction;
//Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm::
private float _ccdSweptSphereRadius;
// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionTreshold
private float _ccdSquareMotionThreshold;
//those two are experimental: just added for bullet time effect, so you can still apply impulses (directly modifying velocities)
//without destroying the continuous interpolated motion (which uses this interpolation velocities)
private Vector3 _interpolationLinearVelocity;
private Vector3 _interpolationAngularVelocity;
private int _companionID;
public CollisionObject()
{
_activationState = ActivationState.Active;
_hitFraction = 1;
}
public bool IsStaticObject { get { return (_collisionFlags & CollisionOptions.StaticObject) != 0; } }
public bool IsKinematicObject { get { return (_collisionFlags & CollisionOptions.KinematicObject) != 0; } }
public bool IsStaticOrKinematicObject { get { return (_collisionFlags & (CollisionOptions.KinematicObject | CollisionOptions.StaticObject)) != 0; } }
public bool HasContactResponse { get { return (_collisionFlags & CollisionOptions.NoContactResponse) == 0; } }
public bool MergesSimulationIslands
{
get
{
//static objects, kinematic and object without contact response don't merge islands
return (_collisionFlags & (CollisionOptions.StaticObject | CollisionOptions.KinematicObject | CollisionOptions.NoContactResponse)) == 0;
}
}
public ActivationState ActivationState
{
get { return _activationState; }
set
{
if ((_activationState != ActivationState.DisableDeactivation) && (_activationState != ActivationState.DisableSimulation))
_activationState = value;
}
}
public bool IsActive { get { return ((ActivationState != ActivationState.IslandSleeping) && (ActivationState != ActivationState.DisableSimulation)); } }
public float Restitution { get { return _restitution; } set { _restitution = value; } }
public float Friction { get { return _friction; } set { _friction = value; } }
public CollisionShape CollisionShape { get { return _collisionShape; } set { _collisionShape = value; } }
public float DeactivationTime { get { return _deactivationTime; } set { _deactivationTime = value; } }
public object Owner { get { return _internalOwner; } protected set { _internalOwner = value; } }
public Matrix WorldTransform { get { return _worldTransform; } set { _worldTransform = value; } }
public BroadphaseProxy Broadphase { get { return _broadphase; } set { _broadphase = value; } }
public Matrix InterpolationWorldTransform { get { return _interpolationWorldTransform; } set { _interpolationWorldTransform = value; } }
public Vector3 InterpolationLinearVelocity { get { return _interpolationLinearVelocity; } protected set { _interpolationLinearVelocity = value; } }
public Vector3 InterpolationAngularVelocity { get { return _interpolationAngularVelocity; } protected set { _interpolationAngularVelocity = value; } }
public int IslandTag { get { return _islandTag; } set { _islandTag = value; } }
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
public CollisionOptions CollisionFlags { get { return _collisionFlags; } set { _collisionFlags = value; } }
//Swept sphere radius (0.0 by default), see btConvexConvexAlgorithm
public float CcdSweptSphereRadius { get { return _ccdSweptSphereRadius; } set { _ccdSweptSphereRadius = value; } }
// Don't do continuous collision detection if square motion (in one step) is less then m_ccdSquareMotionThreshold
public float CcdSquareMotionThreshold { get { return _ccdSquareMotionThreshold; } set { _ccdSquareMotionThreshold = value; } }
//users can point to their objects, userPointer is not used by Bullet
public object UserData { get { return _userData; } set { _userData = value; } }
public int CompanionID { get { return _companionID; } set { _companionID = value; } }
public void ForceActivationState(ActivationState newState)
{
_activationState = newState;
}
public void Activate()
{
Activate(false);
}
public void Activate(bool forceActivation)
{
if (forceActivation || (_collisionFlags & (CollisionOptions.StaticObject | CollisionOptions.KinematicObject)) == 0)
{
ActivationState = ActivationState.Active;
_deactivationTime = 0;
}
}
}
}

View File

@ -0,0 +1,48 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CollisionPairCallback : IOverlapCallback
{
private DispatcherInfo _dispatchInfo;
private CollisionDispatcher _dispatcher;
public CollisionPairCallback(DispatcherInfo dispatchInfo, CollisionDispatcher dispatcher)
{
_dispatchInfo = dispatchInfo;
_dispatcher = dispatcher;
}
#region IOverlapCallback Members
public bool ProcessOverlap(ref BroadphasePair pair)
{
_dispatcher.NearCallback(ref pair, _dispatcher, _dispatchInfo);
return false;
}
#endregion
}
}

View File

@ -0,0 +1,358 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CollisionWorld
{
private List<CollisionObject> _collisionObjects = new List<CollisionObject>();
private IDispatcher _dispatcher;
private OverlappingPairCache _broadphasePairCache;
private bool _ownsDispatcher;
private bool _ownsBroadphasePairCache;
private DispatcherInfo _dispatchInfo = new DispatcherInfo();
/// <summary>
/// this constructor doesn't own the dispatcher and paircache/broadphase
/// </summary>
/// <param name="dispatcher"></param>
/// <param name="pairCache"></param>
public CollisionWorld(IDispatcher dispatcher, OverlappingPairCache pairCache)
{
_dispatcher = dispatcher;
_broadphasePairCache = pairCache;
_ownsDispatcher = false;
_ownsBroadphasePairCache = false;
}
public DispatcherInfo DispatchInfo { get { return _dispatchInfo; } protected set { _dispatchInfo = value; } }
public List<CollisionObject> CollisionObjects { get { return _collisionObjects; } protected set { _collisionObjects = value; } }
public IBroadphase Broadphase { get { return _broadphasePairCache; } }
public OverlappingPairCache BroadphasePairCache { get { return _broadphasePairCache; } protected set { _broadphasePairCache = value; } }
public IDispatcher Dispatcher { get { return _dispatcher; } protected set { _dispatcher = value; } }
public int CollisionObjectsCount { get { return _collisionObjects.Count; } }
protected bool OwnsDispatcher { get { return _ownsDispatcher; } set { _ownsDispatcher = value; } }
protected bool OwnsBroadphasePairCache { get { return _ownsBroadphasePairCache; } set { _ownsBroadphasePairCache = value; } }
// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
{
Matrix rayFromTrans, rayToTrans;
rayFromTrans = Matrix.Identity;
rayFromTrans.Translation = rayFromWorld;
rayToTrans = Matrix.Identity;
rayToTrans.Translation = rayToWorld;
// brute force go over all objects. Once there is a broadphase, use that, or
// add a raycast against aabb first.
foreach (CollisionObject collisionObject in _collisionObjects)
{
//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
Vector3 collisionObjectAabbMin, collisionObjectAabbMax;
collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax);
float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing
Vector3 hitNormal = new Vector3();
//if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax))
if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
{
RayTestSingle(rayFromTrans, rayToTrans,
collisionObject, collisionObject.CollisionShape,
collisionObject.WorldTransform, resultCallback);
}
}
}
// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
// In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
// This allows more customization.
public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
CollisionObject collisionObject,
CollisionShape collisionShape,
Matrix colObjWorldTransform,
RayResultCallback resultCallback)
{
SphereShape pointShape=new SphereShape(0.0f);
if (collisionShape.IsConvex)
{
CastResult castResult = new CastResult();
castResult.Fraction = 1f;//??
ConvexShape convexShape = collisionShape as ConvexShape;
VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
{
//add hit
if (castResult.Normal.LengthSquared() > 0.0001f)
{
castResult.Normal.Normalize();
if (castResult.Fraction < resultCallback.ClosestHitFraction)
{
CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
(
collisionObject,
new LocalShapeInfo(),
castResult.Normal,
castResult.Fraction
);
resultCallback.AddSingleResult(localRayResult);
}
}
}
else
{
if (collisionShape.IsConcave)
{
TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;
Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);
Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);
BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
rcb.HitFraction = resultCallback.ClosestHitFraction;
Vector3 rayAabbMinLocal = rayFromLocal;
MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
Vector3 rayAabbMaxLocal = rayFromLocal;
MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);
triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
}
else
{
//todo: use AABB tree or other BVH acceleration structure!
if (collisionShape.IsCompound)
{
CompoundShape compoundShape = collisionShape as CompoundShape;
for (int i = 0; i < compoundShape.ChildShapeCount; i++)
{
Matrix childTrans = compoundShape.GetChildTransform(i);
CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
Matrix childWorldTrans = colObjWorldTransform * childTrans;
RayTestSingle(rayFromTrans, rayToTrans,
collisionObject,
childCollisionShape,
childWorldTrans,
resultCallback);
}
}
}
}
}
}
public void AddCollisionObject(CollisionObject collisionObject, BroadphaseProxy.CollisionFilterGroups collisionFilterGroup, BroadphaseProxy.CollisionFilterGroups collisionFilterMask)
{
//check that the object isn't already added
if (!_collisionObjects.Contains(collisionObject))
{
_collisionObjects.Add(collisionObject);
//calculate new AABB
Matrix trans = collisionObject.WorldTransform;
Vector3 minAabb;
Vector3 maxAabb;
collisionObject.CollisionShape.GetAabb(trans, out minAabb, out maxAabb);
BroadphaseNativeTypes type = collisionObject.CollisionShape.ShapeType;
collisionObject.Broadphase = Broadphase.CreateProxy(
minAabb,
maxAabb,
type,
collisionObject,
collisionFilterGroup,
collisionFilterMask
);
}
}
public void AddCollisionObject(CollisionObject collisionObject)
{
AddCollisionObject(collisionObject, BroadphaseProxy.CollisionFilterGroups.Default, BroadphaseProxy.CollisionFilterGroups.Default);
}
public void RemoveCollisionObject(CollisionObject collisionObject)
{
BroadphaseProxy bp = collisionObject.Broadphase;
if (bp != null)
{
//
// only clear the cached algorithms
//
Broadphase.CleanProxyFromPairs(bp);
Broadphase.DestroyProxy(bp);
collisionObject.Broadphase = null;
}
_collisionObjects.Remove(collisionObject);
}
public virtual void PerformDiscreteCollisionDetection()
{
DispatcherInfo dispatchInfo = DispatchInfo;
//update aabb (of all moved objects)
Vector3 aabbMin, aabbMax;
for (int i = 0; i < _collisionObjects.Count; i++)
{
_collisionObjects[i].CollisionShape.GetAabb(_collisionObjects[i].WorldTransform, out aabbMin, out aabbMax);
_broadphasePairCache.SetAabb(_collisionObjects[i].Broadphase, aabbMin, aabbMax);
}
_broadphasePairCache.RefreshOverlappingPairs();
IDispatcher dispatcher = Dispatcher;
if (dispatcher != null)
dispatcher.DispatchAllCollisionPairs(_broadphasePairCache, dispatchInfo);
}
public void Dispose(bool disposing)
{
if (disposing)
{
//clean up remaining objects
foreach (CollisionObject collisionObject in _collisionObjects)
{
BroadphaseProxy bp = collisionObject.Broadphase;
if (bp != null)
{
//
// only clear the cached algorithms
//
Broadphase.CleanProxyFromPairs(bp);
Broadphase.DestroyProxy(bp);
}
}
}
}
/// <summary>
/// LocalShapeInfo gives extra information for complex shapes
/// Currently, only TriangleMeshShape is available, so it just contains triangleIndex and subpart
/// </summary>
public struct LocalShapeInfo
{
private int _shapePart;
private int _triangleIndex;
public int ShapePart { get { return _shapePart; } set { _shapePart = value; } }
public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
}
public struct LocalRayResult
{
private CollisionObject _collisionObject;
private LocalShapeInfo _localShapeInfo;
private Vector3 _hitNormalLocal;
private float _hitFraction;
public LocalRayResult(CollisionObject collisionObject,
LocalShapeInfo localShapeInfo,
Vector3 hitNormalLocal,
float hitFraction)
{
_collisionObject = collisionObject;
_localShapeInfo = localShapeInfo;
_hitNormalLocal = hitNormalLocal;
_hitFraction = hitFraction;
}
public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
public LocalShapeInfo LocalShapeInfo { get { return _localShapeInfo; } set { _localShapeInfo = value; } }
public Vector3 HitNormalLocal { get { return _hitNormalLocal; } set { _hitNormalLocal = value; } }
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
}
/// <summary>
/// RayResultCallback is used to report new raycast results
/// </summary>
public abstract class RayResultCallback
{
private float _closestHitFraction;
public RayResultCallback()
{
_closestHitFraction = 1;
}
public float ClosestHitFraction { get { return _closestHitFraction; } set { _closestHitFraction = value; } }
public bool HasHit { get { return _closestHitFraction < 1; } }
public abstract float AddSingleResult(LocalRayResult rayResult);
}
public class ClosestRayResultCallback : RayResultCallback
{
private Vector3 _rayFromWorld;//used to calculate hitPointWorld from hitFraction
private Vector3 _rayToWorld;
private Vector3 _hitNormalWorld;
private Vector3 _hitPointWorld;
private CollisionObject _collisionObject;
public ClosestRayResultCallback(Vector3 rayFromWorld, Vector3 rayToWorld)
{
_rayFromWorld = rayFromWorld;
_rayToWorld = rayToWorld;
_collisionObject = null;
}
public Vector3 RayFromWorld { get { return _rayFromWorld; } set { _rayFromWorld = value; } }
public Vector3 RayToWorld { get { return _rayToWorld; } set { _rayToWorld = value; } }
public Vector3 HitNormalWorld { get { return _hitNormalWorld; } set { _hitNormalWorld = value; } }
public Vector3 HitPointWorld { get { return _hitPointWorld; } set { _hitPointWorld = value; } }
public CollisionObject CollisionObject { get { return _collisionObject; } set { _collisionObject = value; } }
public override float AddSingleResult(LocalRayResult rayResult)
{
//caller already does the filter on the m_closestHitFraction
//assert(rayResult.m_hitFraction <= m_closestHitFraction);
ClosestHitFraction = rayResult.HitFraction;
_collisionObject = rayResult.CollisionObject;
_hitNormalWorld = Vector3.TransformNormal(rayResult.HitNormalLocal, _collisionObject.WorldTransform);
MathHelper.SetInterpolate3(_rayFromWorld, _rayToWorld, rayResult.HitFraction, ref _hitPointWorld);
return rayResult.HitFraction;
}
}
}
}

View File

@ -0,0 +1,157 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using System.Diagnostics;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CompoundCollisionAlgorithm : CollisionAlgorithm
{
private List<CollisionAlgorithm> _childCollisionAlgorithms;
private bool _isSwapped;
public CompoundCollisionAlgorithm(
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo,
CollisionObject bodyA,
CollisionObject bodyB, bool isSwapped)
: base(collisionAlgorithmConstructionInfo)
{
//Begin
_isSwapped = isSwapped;
CollisionObject collisionObject = isSwapped ? bodyB : bodyA;
CollisionObject otherObject = isSwapped ? bodyA : bodyB;
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
CompoundShape compoundShape = collisionObject.CollisionShape as CompoundShape;
int childrenNumber = compoundShape.ChildShapeCount;
int index = 0;
_childCollisionAlgorithms = new List<CollisionAlgorithm>(childrenNumber);
for (index = 0; index < childrenNumber; index++)
{
CollisionShape childShape = compoundShape.GetChildShape(index);
CollisionShape orgShape = collisionObject.CollisionShape;
collisionObject.CollisionShape = childShape;
_childCollisionAlgorithms[index] = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(collisionObject, otherObject);
collisionObject.CollisionShape = orgShape;
}
}
public override void ProcessCollision(
CollisionObject bodyA,
CollisionObject bodyB,
DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
//Begin
CollisionObject collisionObject = _isSwapped ? bodyB : bodyB;
CollisionObject otherObject = _isSwapped ? bodyA : bodyB;
//Debug.Assert(collisionObject.getCollisionShape().isCompound());
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;
int childrenNumber = _childCollisionAlgorithms.Count;
for (int i = 0; i < childrenNumber; i++)
{
CompoundShape childShape = compoundShape.GetChildShape(i) as CompoundShape;
Matrix orgTransform = collisionObject.WorldTransform;
CollisionShape orgShape = collisionObject.CollisionShape;
Matrix childTransform = compoundShape.GetChildTransform(i);
Matrix newChildWorld = orgTransform * childTransform;
collisionObject.WorldTransform = newChildWorld;
collisionObject.CollisionShape = childShape;
_childCollisionAlgorithms[i].ProcessCollision(collisionObject, otherObject, dispatchInfo, resultOut);
collisionObject.CollisionShape = orgShape;
collisionObject.WorldTransform = orgTransform;
}
}
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
CollisionObject collisionObject = _isSwapped ? bodyB : bodyA;
CollisionObject otherObject = _isSwapped ? bodyA : bodyB;
BulletDebug.Assert(collisionObject.CollisionShape.IsCompound);
CompoundShape compoundShape = (CompoundShape)collisionObject.CollisionShape;
float hitFraction = 1.0f;
for (int i = 0; i < _childCollisionAlgorithms.Count; i++)
{
CollisionShape childShape = compoundShape.GetChildShape(i);
Matrix orgTransform = collisionObject.WorldTransform;
CollisionShape orgShape = collisionObject.CollisionShape;
Matrix childTransform = compoundShape.GetChildTransform(i);
Matrix newChildWorld = orgTransform * childTransform;
collisionObject.WorldTransform = newChildWorld;
collisionObject.CollisionShape = childShape;
float frac = _childCollisionAlgorithms[i].CalculateTimeOfImpact(
collisionObject, otherObject, dispatchInfo, resultOut
);
if (frac < hitFraction)
{
hitFraction = frac;
}
collisionObject.CollisionShape = orgShape;
collisionObject.WorldTransform = orgTransform;
}
return hitFraction;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new CompoundCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
}
};
public class SwappedCreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new CompoundCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
}
};
}
}

View File

@ -0,0 +1,189 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class ConvexConcaveCollisionAlgorithm : CollisionAlgorithm
{
private bool _isSwapped;
private ConvexTriangleCallback _convexTriangleCallback;
public ConvexConcaveCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
: base(collisionAlgorithmConstructionInfo)
{
_isSwapped = isSwapped;
_convexTriangleCallback = new ConvexTriangleCallback(collisionAlgorithmConstructionInfo.Dispatcher, bodyA, bodyB, isSwapped);
}
public void ClearCache()
{
_convexTriangleCallback.ClearCache();
}
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
CollisionObject convexBody = _isSwapped ? bodyB : bodyA;
CollisionObject triBody = _isSwapped ? bodyA : bodyB;
if (triBody.CollisionShape.IsConcave)
{
CollisionObject triOb = triBody;
ConcaveShape concaveShape = triOb.CollisionShape as ConcaveShape;
if (convexBody.CollisionShape.IsConvex)
{
float collisionMarginTriangle = concaveShape.Margin;
resultOut.SetPersistentManifold(_convexTriangleCallback.Manifold);
_convexTriangleCallback.SetTimeStepAndCounters(collisionMarginTriangle, dispatchInfo, resultOut);
//Disable persistency. previously, some older algorithm calculated all contacts in one go, so you can clear it here.
//m_dispatcher->clearManifold(m_btConvexTriangleCallback.m_manifoldPtr);
_convexTriangleCallback.Manifold.SetBodies(convexBody, triBody);
concaveShape.ProcessAllTriangles(_convexTriangleCallback, _convexTriangleCallback.AabbMin, _convexTriangleCallback.AabbMax);
}
}
}
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
CollisionObject convexbody = _isSwapped ? bodyB : bodyA;
CollisionObject triBody = _isSwapped ? bodyA : bodyB;
//quick approximation using raycast, todo: hook up to the continuous collision detection (one of the btConvexCast)
//only perform CCD above a certain threshold, this prevents blocking on the long run
//because object in a blocked ccd state (hitfraction<1) get their linear velocity halved each frame...
float squareMot0 = (convexbody.InterpolationWorldTransform.Translation - convexbody.WorldTransform.Translation).LengthSquared();
if (squareMot0 < convexbody.CcdSquareMotionThreshold)
{
return 1;
}
Matrix triInv = MathHelper.InvertMatrix(triBody.WorldTransform);
Matrix convexFromLocal = triInv * convexbody.WorldTransform;
Matrix convexToLocal = triInv * convexbody.InterpolationWorldTransform;
if (triBody.CollisionShape.IsConcave)
{
Vector3 rayAabbMin = convexFromLocal.Translation;
MathHelper.SetMin(ref rayAabbMin, convexToLocal.Translation);
Vector3 rayAabbMax = convexFromLocal.Translation;
MathHelper.SetMax(ref rayAabbMax, convexToLocal.Translation);
float ccdRadius0 = convexbody.CcdSweptSphereRadius;
rayAabbMin -= new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);
rayAabbMax += new Vector3(ccdRadius0, ccdRadius0, ccdRadius0);
float curHitFraction = 1f; //is this available?
LocalTriangleSphereCastCallback raycastCallback = new LocalTriangleSphereCastCallback(convexFromLocal, convexToLocal,
convexbody.CcdSweptSphereRadius, curHitFraction);
raycastCallback.HitFraction = convexbody.HitFraction;
CollisionObject concavebody = triBody;
ConcaveShape triangleMesh = concavebody.CollisionShape as ConcaveShape;
if (triangleMesh != null)
{
triangleMesh.ProcessAllTriangles(raycastCallback, rayAabbMin, rayAabbMax);
}
if (raycastCallback.HitFraction < convexbody.HitFraction)
{
convexbody.HitFraction = raycastCallback.HitFraction;
return raycastCallback.HitFraction;
}
}
return 1;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new ConvexConcaveCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
}
}
public class SwappedCreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new ConvexConcaveCollisionAlgorithm(collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
}
}
private class LocalTriangleSphereCastCallback : ITriangleCallback
{
private Matrix _ccdSphereFromTrans;
private Matrix _ccdSphereToTrans;
private Matrix _meshTransform;
private float _ccdSphereRadius;
private float _hitFraction;
public LocalTriangleSphereCastCallback(Matrix from, Matrix to, float ccdSphereRadius, float hitFraction)
{
_ccdSphereFromTrans = from;
_ccdSphereToTrans = to;
_ccdSphereRadius = ccdSphereRadius;
_hitFraction = hitFraction;
}
public Matrix CcdSphereFromTrans { get { return _ccdSphereFromTrans; } set { _ccdSphereFromTrans = value; } }
public Matrix CcdSphereToTrans { get { return _ccdSphereToTrans; } set { _ccdSphereToTrans = value; } }
public Matrix MeshTransform { get { return _meshTransform; } set { _meshTransform = value; } }
public float CcdSphereRadius { get { return _ccdSphereRadius; } set { _ccdSphereRadius = value; } }
public float HitFraction { get { return _hitFraction; } set { _hitFraction = value; } }
public void ProcessTriangle(Vector3[] triangle, int partId, int triangleIndex)
{
//do a swept sphere for now
Matrix ident = Matrix.Identity;
CastResult castResult = new CastResult();
castResult.Fraction = _hitFraction;
SphereShape pointShape = new SphereShape(_ccdSphereRadius);
TriangleShape triShape = new TriangleShape(triangle[0], triangle[1], triangle[2]);
VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, triShape, simplexSolver);
//GjkConvexCast convexCaster(&pointShape,convexShape,&simplexSolver);
//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);
//local space?
if (convexCaster.CalcTimeOfImpact(_ccdSphereFromTrans, _ccdSphereToTrans,
ident, ident, castResult))
{
if (_hitFraction > castResult.Fraction)
_hitFraction = castResult.Fraction;
}
}
}
}
}

View File

@ -0,0 +1,193 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public class ConvexConvexAlgorithm : CollisionAlgorithm, IDisposable
{
private const bool DisableCcd = false;
private GjkPairDetector _gjkPairDetector;
private bool _ownManifold;
private PersistentManifold _manifold;
private bool _lowLevelOfDetail;
public ConvexConvexAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
: base(collisionAlgorithmConstructionInfo)
{
_gjkPairDetector = new GjkPairDetector(null, null, simplexSolver, penetrationDepthSolver);
_ownManifold = false;
_manifold = manifold;
_lowLevelOfDetail = false;
}
public bool LowLevelOfDetail { get { return _lowLevelOfDetail; } set { _lowLevelOfDetail = value; } }
public bool OwnManifold { get { return _ownManifold; } set { _ownManifold = value; } }
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
if (_manifold == null)
{
//swapped?
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
_ownManifold = true;
}
resultOut.SetPersistentManifold(_manifold);
ConvexShape min0 = bodyA.CollisionShape as ConvexShape;
ConvexShape min1 = bodyB.CollisionShape as ConvexShape;
GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
//TODO: if (dispatchInfo.m_useContinuous)
_gjkPairDetector.setMinkowskiA(min0);
_gjkPairDetector.setMinkowskiB(min1);
input.MaximumDistanceSquared = min0.Margin + min1.Margin + PersistentManifold.ContactBreakingThreshold;
input.MaximumDistanceSquared *= input.MaximumDistanceSquared;
// input.m_maximumDistanceSquared = 1e30f;
input.TransformA = bodyA.WorldTransform;
input.TransformB = bodyB.WorldTransform;
_gjkPairDetector.GetClosestPoints(input, resultOut, dispatchInfo.DebugDraw);
}
public override float CalculateTimeOfImpact(CollisionObject colA, CollisionObject colB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
//Rather then checking ALL pairs, only calculate TOI when motion exceeds threshold
//Linear motion for one of objects needs to exceed m_ccdSquareMotionThreshold
//col0->m_worldTransform,
float resultFraction = 1f;
float squareMotA = (colA.InterpolationWorldTransform.Translation - colA.WorldTransform.Translation).LengthSquared();
float squareMotB = (colB.InterpolationWorldTransform.Translation - colB.WorldTransform.Translation).LengthSquared();
if (squareMotA < colA.CcdSquareMotionThreshold &&
squareMotB < colB.CcdSquareMotionThreshold)
return resultFraction;
if (DisableCcd)
return 1f;
//An adhoc way of testing the Continuous Collision Detection algorithms
//One object is approximated as a sphere, to simplify things
//Starting in penetration should report no time of impact
//For proper CCD, better accuracy and handling of 'allowed' penetration should be added
//also the mainloop of the physics should have a kind of toi queue (something like Brian Mirtich's application of Timewarp for Rigidbodies)
// Convex0 against sphere for Convex1
{
ConvexShape convexA = colA.CollisionShape as ConvexShape;
SphereShape sphereB = new SphereShape(colB.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
CastResult result = new CastResult();
VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
//Simplification, one object is simplified as a sphere
GjkConvexCast ccdB = new GjkConvexCast(convexA, sphereB, voronoiSimplex);
//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
colB.WorldTransform, colB.InterpolationWorldTransform, result))
{
//store result.m_fraction in both bodies
if (colA.HitFraction > result.Fraction)
colA.HitFraction = result.Fraction;
if (colB.HitFraction > result.Fraction)
colB.HitFraction = result.Fraction;
if (resultFraction > result.Fraction)
resultFraction = result.Fraction;
}
}
// Sphere (for convex0) against Convex1
{
ConvexShape convexB = colB.CollisionShape as ConvexShape;
SphereShape sphereA = new SphereShape(colA.CcdSweptSphereRadius); //todo: allow non-zero sphere sizes, for better approximation
CastResult result = new CastResult();
VoronoiSimplexSolver voronoiSimplex = new VoronoiSimplexSolver();
//SubsimplexConvexCast ccd0(&sphere,min0,&voronoiSimplex);
///Simplification, one object is simplified as a sphere
GjkConvexCast ccdB = new GjkConvexCast(sphereA, convexB, voronoiSimplex);
//ContinuousConvexCollision ccd(min0,min1,&voronoiSimplex,0);
if (ccdB.CalcTimeOfImpact(colA.WorldTransform, colA.InterpolationWorldTransform,
colB.WorldTransform, colB.InterpolationWorldTransform, result))
{
//store result.m_fraction in both bodies
if (colA.HitFraction > result.Fraction)
colA.HitFraction = result.Fraction;
if (colB.HitFraction > result.Fraction)
colB.HitFraction = result.Fraction;
if (resultFraction > result.Fraction)
resultFraction = result.Fraction;
}
}
return resultFraction;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
private IConvexPenetrationDepthSolver _penetrationDepthSolver;
private ISimplexSolver _simplexSolver;
//private bool _ownsSolvers;
public CreateFunc()
{
//_ownsSolvers = true;
_simplexSolver = new VoronoiSimplexSolver();
_penetrationDepthSolver = new GjkEpaPenetrationDepthSolver();
}
public CreateFunc(ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
{
//_ownsSolvers = false;
_simplexSolver = simplexSolver;
_penetrationDepthSolver = penetrationDepthSolver;
}
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new ConvexConvexAlgorithm(collisionAlgorithmConstructionInfo.Manifold, collisionAlgorithmConstructionInfo, bodyA, bodyB, _simplexSolver, _penetrationDepthSolver);
}
}
#region IDisposable Members
public void Dispose()
{
if (_ownManifold)
{
if (_manifold != null)
Dispatcher.ReleaseManifold(_manifold);
}
}
#endregion
}
}

View File

@ -0,0 +1,130 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class ConvexTriangleCallback : ITriangleCallback, IDisposable
{
private CollisionObject _convexBody;
private CollisionObject _triBody;
private Vector3 _aabbMin;
private Vector3 _aabbMax;
private ManifoldResult _resultOut;
private IDispatcher _dispatcher;
private DispatcherInfo _dispatchInfo;
private float _collisionMarginTriangle;
private int _triangleCount;
private PersistentManifold _manifold;
public ConvexTriangleCallback(IDispatcher dispatcher, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
{
_dispatcher = dispatcher;
_dispatchInfo = null;
_convexBody = isSwapped ? bodyB : bodyA;
_triBody = isSwapped ? bodyA : bodyB;
// create the manifold from the dispatcher 'manifold pool'
_manifold = _dispatcher.GetNewManifold(_convexBody, _triBody);
ClearCache();
}
public Vector3 AabbMin { get { return _aabbMin; } }
public Vector3 AabbMax { get { return _aabbMax; } }
public int TriangleCount { get { return _triangleCount; } set { _triangleCount = value; } }
public PersistentManifold Manifold { get { return _manifold; } set { _manifold = value; } }
public void SetTimeStepAndCounters(float collisionMarginTriangle, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
_dispatchInfo = dispatchInfo;
_collisionMarginTriangle = collisionMarginTriangle;
_resultOut = resultOut;
//recalc aabbs
Matrix convexInTriangleSpace = MathHelper.InvertMatrix(_triBody.WorldTransform) * _convexBody.WorldTransform;
CollisionShape convexShape = _convexBody.CollisionShape;
//CollisionShape* triangleShape = static_cast<btCollisionShape*>(triBody->m_collisionShape);
convexShape.GetAabb(convexInTriangleSpace, out _aabbMin, out _aabbMax);
float extraMargin = collisionMarginTriangle;
Vector3 extra = new Vector3(extraMargin, extraMargin, extraMargin);
_aabbMax += extra;
_aabbMin -= extra;
}
public void ClearCache()
{
_dispatcher.ClearManifold(_manifold);
}
#region ITriangleCallback Members
public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex)
{
//aabb filter is already applied!
CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo = new CollisionAlgorithmConstructionInfo();
collisionAlgorithmConstructionInfo.Dispatcher = _dispatcher;
CollisionObject collisionObject = _triBody;
//debug drawing of the overlapping triangles
/*if (m_dispatchInfoPtr && m_dispatchInfoPtr.m_debugDraw && m_dispatchInfoPtr->m_debugDraw->getDebugMode() > 0)
{
Vector3 color = new Vector3(255, 255, 0);
btTransform & tr = ob->WorldTransform;
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[0]), tr(triangle[1]), color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[1]), tr(triangle[2]), color);
m_dispatchInfoPtr->m_debugDraw->drawLine(tr(triangle[2]), tr(triangle[0]), color);
}*/
if (_convexBody.CollisionShape.IsConvex)
{
TriangleShape triangleShape = new TriangleShape(triangle[0], triangle[1], triangle[2]);
triangleShape.Margin=_collisionMarginTriangle;
CollisionShape tempShape = collisionObject.CollisionShape;
collisionObject.CollisionShape = triangleShape;
CollisionAlgorithm collisionAlgorithm = collisionAlgorithmConstructionInfo.Dispatcher.FindAlgorithm(_convexBody, _triBody, _manifold);
_resultOut.SetShapeIdentifiers(-1, -1, partID, triangleIndex);
collisionAlgorithm.ProcessCollision(_convexBody, _triBody, _dispatchInfo, _resultOut);
collisionObject.CollisionShape = tempShape;
}
}
#endregion
#region IDisposable Members
public void Dispose()
{
ClearCache();
_dispatcher.ReleaseManifold(_manifold);
}
#endregion
}
}

View File

@ -0,0 +1,52 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
/// <summary>
/// EmptyAlgorithm is a stub for unsupported collision pairs.
/// The dispatcher can dispatch a persistent btEmptyAlgorithm to avoid a search every frame.
/// </summary>
public class EmptyAlgorithm : CollisionAlgorithm
{
public EmptyAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
: base(collisionAlgorithmConstructionInfo) { }
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut) { }
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
return 1f;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new EmptyAlgorithm(collisionAlgorithmConstructionInfo);
}
};
}
}

View File

@ -0,0 +1,147 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public delegate bool ContactAddedCallback(ManifoldPoint contactPoint, CollisionObject collisionObjectA, int partIdA, int indexA, CollisionObject collisionObjectB, int partIdB, int indexB);
public class ManifoldResult : DiscreteCollisionDetectorInterface.Result
{
private PersistentManifold _manifold;
private static ContactAddedCallback _contactAddedCallback = null;
//we need this for compounds
private Matrix _rootTransA;
private Matrix _rootTransB;
private CollisionObject _bodyA;
private CollisionObject _bodyB;
private int _partIdA;
private int _partIdB;
private int _indexA;
private int _indexB;
public ManifoldResult()
{
}
public ManifoldResult(CollisionObject bodyA, CollisionObject bodyB)
{
_bodyA = bodyA;
_bodyB = bodyB;
_rootTransA = bodyA.WorldTransform;
_rootTransB = bodyB.WorldTransform;
}
public static ContactAddedCallback ContactAddedCallback { get { return _contactAddedCallback; } set { _contactAddedCallback = value; } }
public void SetPersistentManifold(PersistentManifold manifold)
{
_manifold = manifold;
}
public override void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB)
{
_partIdA = partIdA;
_partIdB = partIdB;
_indexA = indexA;
_indexB = indexB;
}
public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
{
if (_manifold == null)
throw new BulletException("Manifold Pointer is null.");
//order in manifold needs to match
if (depth > PersistentManifold.ContactBreakingThreshold)
return;
bool isSwapped = _manifold.BodyA != _bodyA;
Vector3 pointA = pointInWorld + normalOnBInWorld * depth;
Vector3 localA;
Vector3 localB;
if (isSwapped)
{
localA = MathHelper.InvXForm(_rootTransB, pointA);
localB = MathHelper.InvXForm(_rootTransA, pointInWorld);
}
else
{
localA = MathHelper.InvXForm(_rootTransA, pointA);
localB = MathHelper.InvXForm(_rootTransB, pointInWorld);
}
ManifoldPoint newPt = new ManifoldPoint(localA, localB, normalOnBInWorld, depth);
int insertIndex = _manifold.GetCacheEntry(newPt);
newPt.CombinedFriction = CalculateCombinedFriction(_bodyA, _bodyB);
newPt.CombinedRestitution = CalculateCombinedRestitution(_bodyA, _bodyB);
//User can override friction and/or restitution
if (_contactAddedCallback != null &&
//and if either of the two bodies requires custom material
((_bodyA.CollisionFlags & CollisionOptions.CustomMaterialCallback) != 0 ||
(_bodyB.CollisionFlags & CollisionOptions.CustomMaterialCallback) != 0))
{
//experimental feature info, for per-triangle material etc.
CollisionObject obj0 = isSwapped ? _bodyB : _bodyA;
CollisionObject obj1 = isSwapped ? _bodyA : _bodyB;
_contactAddedCallback(newPt, obj0, _partIdA, _indexA, obj1, _partIdB, _indexB);
}
if (insertIndex >= 0)
{
_manifold.ReplaceContactPoint(newPt, insertIndex);
}
else
{
_manifold.AddManifoldPoint(newPt);
}
}
private float CalculateCombinedFriction(CollisionObject bodyA, CollisionObject bodyB)
{
float friction = bodyA.Friction * bodyB.Friction;
float MaxFriction = 10;
if (friction < -MaxFriction)
friction = -MaxFriction;
if (friction > MaxFriction)
friction = MaxFriction;
return friction;
}
private float CalculateCombinedRestitution(CollisionObject bodyA, CollisionObject bodyB)
{
return bodyA.Restitution * bodyB.Restitution;
}
}
}

View File

@ -0,0 +1,304 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class SimulationIslandManager
{
private UnionFind _unionFind = new UnionFind();
public void InitUnionFind(int n)
{
_unionFind.Reset(n);
}
public UnionFind UnionFind { get { return _unionFind; } }
public virtual void UpdateActivationState(CollisionWorld world, IDispatcher dispatcher)
{
InitUnionFind(world.CollisionObjectsCount);
// put the index into m_controllers into m_tag
int index = 0;
for (int i = 0; i < world.CollisionObjects.Count; i++)
{
world.CollisionObjects[i].IslandTag = index;
world.CollisionObjects[i].HitFraction = 1;
world.CollisionObjects[i].CompanionID = -1;
index++;
}
// do the union find
FindUnions(dispatcher);
}
public virtual void StoreIslandActivationState(CollisionWorld world)
{
// put the islandId ('find' value) into m_tag
int index = 0;
for (int i = 0; i < world.CollisionObjects.Count; i++)
{
if (world.CollisionObjects[i].MergesSimulationIslands)
{
world.CollisionObjects[i].IslandTag = _unionFind.Find(index);
world.CollisionObjects[i].CompanionID = -1;
}
else
{
world.CollisionObjects[i].IslandTag = -1;
world.CollisionObjects[i].CompanionID = -2;
}
index++;
}
}
public void FindUnions(IDispatcher dispatcher)
{
for (int i = 0; i < dispatcher.ManifoldCount; i++)
{
PersistentManifold manifold = dispatcher.GetManifoldByIndex(i);
//static objects (invmass 0.f) don't merge !
CollisionObject colObjA = manifold.BodyA as CollisionObject;
CollisionObject colObjB = manifold.BodyB as CollisionObject;
if (((colObjA != null) && (colObjA.MergesSimulationIslands)) &&
((colObjB != null) && (colObjB.MergesSimulationIslands)))
{
_unionFind.Unite(colObjA.IslandTag, colObjB.IslandTag);
}
}
}
public void BuildAndProcessIslands(IDispatcher dispatcher, List<CollisionObject> collisionObjects, IIslandCallback callback)
{
//we are going to sort the unionfind array, and store the element id in the size
//afterwards, we clean unionfind, to make sure no-one uses it anymore
UnionFind.SortIslands();
int numElem = UnionFind.ElementCount;
int endIslandIndex = 1;
int startIslandIndex;
//update the sleeping state for bodies, if all are sleeping
for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
{
int islandId = UnionFind[startIslandIndex].ID;
for (endIslandIndex = startIslandIndex + 1; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
{
}
//int numSleeping = 0;
bool allSleeping = true;
int idx;
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
{
int i = UnionFind[idx].Size;
CollisionObject colObjA = collisionObjects[i];
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
{
Console.WriteLine("error in island management");
}
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
if (colObjA.IslandTag == islandId)
{
if (colObjA.ActivationState == ActivationState.Active)
{
allSleeping = false;
}
if (colObjA.ActivationState == ActivationState.DisableDeactivation)
{
allSleeping = false;
}
}
}
if (allSleeping)
{
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
{
int i = UnionFind[idx].Size;
CollisionObject colObjA = collisionObjects[i];
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
{
Console.WriteLine("error in island management");
}
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
if (colObjA.IslandTag == islandId)
{
colObjA.ActivationState =ActivationState.IslandSleeping;
}
}
}
else
{
for (idx = startIslandIndex; idx < endIslandIndex; idx++)
{
int i = UnionFind[idx].Size;
CollisionObject colObjA = collisionObjects[i];
if ((colObjA.IslandTag != islandId) && (colObjA.IslandTag != -1))
{
Console.WriteLine("error in island management");
}
BulletDebug.Assert((colObjA.IslandTag == islandId) || (colObjA.IslandTag == -1));
if (colObjA.IslandTag == islandId)
{
if (colObjA.ActivationState == ActivationState.IslandSleeping)
{
colObjA.ActivationState = ActivationState.WantsDeactivation;
}
}
}
}
}
//int maxNumManifolds = dispatcher.ManifoldCount;
List<PersistentManifold> islandmanifold = new List<PersistentManifold>(dispatcher.ManifoldCount);
for (int i = 0; i < dispatcher.ManifoldCount; i++)
{
PersistentManifold manifold = dispatcher.GetManifoldByIndex(i);
CollisionObject colObjA = manifold.BodyA as CollisionObject;
CollisionObject colObjB = manifold.BodyB as CollisionObject;
//todo: check sleeping conditions!
if (((colObjA != null) && colObjA.ActivationState != ActivationState.IslandSleeping) ||
((colObjB != null) && colObjB.ActivationState != ActivationState.IslandSleeping))
{
//kinematic objects don't merge islands, but wake up all connected objects
if (colObjA.IsStaticOrKinematicObject && colObjA.ActivationState != ActivationState.IslandSleeping)
{
colObjB.Activate();
}
if (colObjB.IsStaticOrKinematicObject && colObjB.ActivationState != ActivationState.IslandSleeping)
{
colObjA.Activate();
}
//filtering for response
if (dispatcher.NeedsResponse(colObjA, colObjB))
islandmanifold.Add(manifold);
}
}
int numManifolds = islandmanifold.Count;
// Sort manifolds, based on islands
// Sort the vector using predicate and std::sort
islandmanifold.Sort(new Comparison<PersistentManifold>(PersistentManifoldSortPredicate));
//now process all active islands (sets of manifolds for now)
int startManifoldIndex = 0;
int endManifoldIndex = 1;
List<CollisionObject> islandBodies = new List<CollisionObject>();
for (startIslandIndex = 0; startIslandIndex < numElem; startIslandIndex = endIslandIndex)
{
int islandId = UnionFind[startIslandIndex].ID;
bool islandSleeping = false;
for (endIslandIndex = startIslandIndex; (endIslandIndex < numElem) && (UnionFind[endIslandIndex].ID == islandId); endIslandIndex++)
{
int i = UnionFind[endIslandIndex].Size;
CollisionObject colObjA = collisionObjects[i];
islandBodies.Add(colObjA);
if (!colObjA.IsActive)
islandSleeping = true;
}
//find the accompanying contact manifold for this islandId
int numIslandManifolds = 0;
List<PersistentManifold> startManifold = new List<PersistentManifold>(numIslandManifolds);
if (startManifoldIndex < numManifolds)
{
int curIslandID = GetIslandId(islandmanifold[startManifoldIndex]);
if (curIslandID == islandId)
{
for (int k = startManifoldIndex; k < islandmanifold.Count; k++)
{
startManifold.Add(islandmanifold[k]);
}
for (endManifoldIndex = startManifoldIndex + 1; (endManifoldIndex < numManifolds) && (islandId == GetIslandId(islandmanifold[endManifoldIndex])); endManifoldIndex++) { }
// Process the actual simulation, only if not sleeping/deactivated
numIslandManifolds = endManifoldIndex - startManifoldIndex;
}
}
if (!islandSleeping)
{
callback.ProcessIsland(islandBodies, startManifold, numIslandManifolds, islandId);
}
if (numIslandManifolds != 0)
{
startManifoldIndex = endManifoldIndex;
}
islandBodies.Clear();
}
}
private static int GetIslandId(PersistentManifold lhs)
{
int islandId;
CollisionObject rcolObjA = lhs.BodyA as CollisionObject;
CollisionObject rcolObjB = lhs.BodyB as CollisionObject;
islandId = rcolObjA.IslandTag >= 0 ? rcolObjA.IslandTag : rcolObjB.IslandTag;
return islandId;
}
private static int PersistentManifoldSortPredicate(PersistentManifold lhs, PersistentManifold rhs)
{
int rIslandIdA, lIslandIdB;
rIslandIdA = GetIslandId(rhs);
lIslandIdB = GetIslandId(lhs);
//return lIslandId0 < rIslandId0;
if (lIslandIdB < rIslandIdA)
return -1;
//else if (lIslandIdB > rIslandIdA)
// return 1;
return 1;
}
public interface IIslandCallback
{
void ProcessIsland(List<CollisionObject> bodies, List<PersistentManifold> manifolds, int numManifolds, int islandID);
}
}
}

View File

@ -0,0 +1,270 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// SphereBoxCollisionAlgorithm provides sphere-box collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
/// </summary>
public class SphereBoxCollisionAlgorithm : CollisionAlgorithm, IDisposable
{
private bool _ownManifold;
private PersistentManifold _manifold;
private bool _isSwapped;
public SphereBoxCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject collisionObjectA, CollisionObject collisionObjectB, bool isSwapped)
: base(collisionAlgorithmConstructionInfo)
{
_ownManifold = false;
_manifold = manifold;
_isSwapped = isSwapped;
CollisionObject sphereObject = _isSwapped ? collisionObjectB : collisionObjectA;
CollisionObject boxObject = _isSwapped ? collisionObjectA : collisionObjectB;
if (_manifold == null && Dispatcher.NeedsCollision(sphereObject, boxObject))
{
_manifold = Dispatcher.GetNewManifold(sphereObject, boxObject);
_ownManifold = true;
}
}
public float GetSphereDistance(CollisionObject boxObject, out Vector3 pointOnBox, out Vector3 pointOnSphere, Vector3 sphereCenter, float radius)
{
pointOnBox = new Vector3();
pointOnSphere = new Vector3();
float margins;
Vector3[] bounds = new Vector3[2];
BoxShape boxShape = boxObject.CollisionShape as BoxShape;
bounds[0] = -boxShape.HalfExtents;
bounds[1] = boxShape.HalfExtents;
margins = boxShape.Margin; //also add sphereShape margin?
Matrix m44T = boxObject.WorldTransform;
Vector3[] boundsVec = new Vector3[2];
float penetration;
boundsVec[0] = bounds[0];
boundsVec[1] = bounds[1];
Vector3 marginsVec = new Vector3(margins, margins, margins);
// add margins
bounds[0] += marginsVec;
bounds[1] -= marginsVec;
/////////////////////////////////////////////////
Vector3 tmp, prel, normal, v3P;
Vector3[] n = new Vector3[6];
float sep = 10000000.0f, sepThis;
n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
n[1] = new Vector3(0.0f, -1.0f, 0.0f);
n[2] = new Vector3(0.0f, 0.0f, -1.0f);
n[3] = new Vector3(1.0f, 0.0f, 0.0f);
n[4] = new Vector3(0.0f, 1.0f, 0.0f);
n[5] = new Vector3(0.0f, 0.0f, 1.0f);
// convert point in local space
prel = MathHelper.InvXForm(m44T, sphereCenter);
bool found = false;
v3P = prel;
for (int i = 0; i < 6; i++)
{
int j = i < 3 ? 0 : 1;
if ((sepThis = (Vector3.Dot(v3P - bounds[j], n[i]))) > 0.0f)
{
v3P = v3P - n[i] * sepThis;
found = true;
}
}
//
if (found)
{
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
normal = Vector3.Normalize(prel - v3P);
pointOnBox = v3P + normal * margins;
pointOnSphere = prel - normal * radius;
if ((Vector3.Dot(pointOnSphere - pointOnBox, normal)) > 0.0f)
{
return 1.0f;
}
// transform back in world space
tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
pointOnBox = tmp;
tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
pointOnSphere = tmp;
float seps2 = (pointOnBox - pointOnSphere).LengthSquared();
//if this fails, fallback into deeper penetration case, below
if (seps2 > MathHelper.Epsilon)
{
sep = -(float)Math.Sqrt(seps2);
normal = (pointOnBox - pointOnSphere);
normal *= 1f / sep;
}
return sep;
}
//////////////////////////////////////////////////
// Deep penetration case
penetration = GetSpherePenetration(boxObject, ref pointOnBox, ref pointOnSphere, sphereCenter, radius, bounds[0], bounds[1]);
bounds[0] = boundsVec[0];
bounds[1] = boundsVec[1];
if (penetration <= 0.0f)
return (penetration - margins);
else
return 1.0f;
}
public float GetSpherePenetration(CollisionObject boxObject, ref Vector3 pointOnBox, ref Vector3 pointOnSphere, Vector3 sphereCenter, float radius, Vector3 aabbMin, Vector3 aabbMax)
{
Vector3[] bounds = new Vector3[2];
bounds[0] = aabbMin;
bounds[1] = aabbMax;
Vector3 p0 = new Vector3(), tmp, prel, normal = new Vector3();
Vector3[] n = new Vector3[6];
float sep = -10000000.0f, sepThis;
n[0] = new Vector3(-1.0f, 0.0f, 0.0f);
n[1] = new Vector3(0.0f, -1.0f, 0.0f);
n[2] = new Vector3(0.0f, 0.0f, -1.0f);
n[3] = new Vector3(1.0f, 0.0f, 0.0f);
n[4] = new Vector3(0.0f, 1.0f, 0.0f);
n[5] = new Vector3(0.0f, 0.0f, 1.0f);
Matrix m44T = boxObject.WorldTransform;
// convert point in local space
prel = MathHelper.InvXForm(m44T, sphereCenter);
///////////
for (int i = 0; i < 6; i++)
{
int j = i < 3 ? 0 : 1;
if ((sepThis = (Vector3.Dot(prel - bounds[j], n[i])) - radius) > 0.0f) return 1.0f;
if (sepThis > sep)
{
p0 = bounds[j];
normal = n[i];
sep = sepThis;
}
}
pointOnBox = prel - normal * (Vector3.Dot(normal, (prel - p0)));
pointOnSphere = pointOnBox + normal * sep;
// transform back in world space
tmp = MathHelper.MatrixToVector(m44T, pointOnBox);
pointOnBox = tmp;
tmp = MathHelper.MatrixToVector(m44T, pointOnSphere);
pointOnSphere = tmp;
normal = Vector3.Normalize(pointOnBox - pointOnSphere);
return sep;
}
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
if (_manifold == null)
return;
CollisionObject sphereObject = _isSwapped ? bodyB : bodyA;
CollisionObject boxObject = _isSwapped ? bodyA : bodyB;
SphereShape sphereA = sphereObject.CollisionShape as SphereShape;
Vector3 pOnBox, pOnSphere;
Vector3 sphereCenter = sphereObject.WorldTransform.Translation;
float radius = sphereA.Radius;
float dist = GetSphereDistance(boxObject, out pOnBox, out pOnSphere, sphereCenter, radius);
if (dist < MathHelper.Epsilon)
{
Vector3 normalOnSurfaceB = Vector3.Normalize(pOnBox - pOnSphere);
// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut.SetPersistentManifold(_manifold);
resultOut.AddContactPoint(normalOnSurfaceB, pOnBox, dist);
}
}
public override float CalculateTimeOfImpact(CollisionObject collisionObjectA, CollisionObject collisionObjectB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
//not yet
return 1;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
if (!IsSwapped)
return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, false);
else
return new SphereBoxCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB, true);
}
}
#region IDisposable Members
public void Dispose()
{
Dispose(true);
}
public void Dispose(bool disposing)
{
if (disposing && _ownManifold)
{
if (_manifold != null)
Dispatcher.ReleaseManifold(_manifold);
}
}
#endregion
}
}

View File

@ -0,0 +1,104 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class SphereSphereCollisionAlgorithm : CollisionAlgorithm
{
private bool _ownManifold;
private PersistentManifold _manifold;
public SphereSphereCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
: base(collisionAlgorithmConstructionInfo)
{
_ownManifold = false;
_manifold = manifold;
if (_manifold == null)
{
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
_ownManifold = true;
}
}
public SphereSphereCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
: base(collisionAlgorithmConstructionInfo) { }
~SphereSphereCollisionAlgorithm()
{
if (_ownManifold)
{
if (_manifold != null)
Dispatcher.ReleaseManifold(_manifold);
}
}
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
if (_manifold == null)
return;
SphereShape sphereA = bodyA.CollisionShape as SphereShape;
SphereShape sphereB = bodyB.CollisionShape as SphereShape;
Vector3 diff = bodyA.WorldTransform.Translation - bodyB.WorldTransform.Translation;
float len = diff.Length();
float radiusA = sphereA.Radius;
float radiusB = sphereB.Radius;
//if distance positive, don't generate a new contact
if (len > (radiusA + radiusB))
return;
//distance (negative means penetration)
float dist = len - (radiusA + radiusB);
Vector3 normalOnSurfaceB = diff / len;
//point on A (worldspace)
Vector3 posA = bodyA.WorldTransform.Translation - radiusA * normalOnSurfaceB;
//point on B (worldspace)
Vector3 posB = bodyB.WorldTransform.Translation + radiusB * normalOnSurfaceB;
// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut.SetPersistentManifold(_manifold);
resultOut.AddContactPoint(normalOnSurfaceB, posB, dist);
}
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
//not yet
return 1f;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new SphereSphereCollisionAlgorithm(null, collisionAlgorithmConstructionInfo, bodyA, bodyB);
}
}
}
}

View File

@ -0,0 +1,100 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// SphereSphereCollisionAlgorithm provides sphere-sphere collision detection.
/// Other features are frame-coherency (persistent data) and collision response.
/// Also provides the most basic sample for custom/user btCollisionAlgorithm
/// </summary>
public class SphereTriangleCollisionAlgorithm : CollisionAlgorithm, IDisposable
{
private bool _ownManifold;
private PersistentManifold _manifold;
private bool _isSwapped;
public SphereTriangleCollisionAlgorithm(PersistentManifold manifold, CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB, bool isSwapped)
: base(collisionAlgorithmConstructionInfo)
{
_ownManifold = false;
_manifold = manifold;
_isSwapped = isSwapped;
if (_manifold == null)
{
_manifold = Dispatcher.GetNewManifold(bodyA, bodyB);
_ownManifold = true;
}
}
public SphereTriangleCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo)
: base(collisionAlgorithmConstructionInfo) { }
public override void ProcessCollision(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
if (_manifold == null)
return;
SphereShape sphere = bodyA.CollisionShape as SphereShape;
TriangleShape triangle = bodyB.CollisionShape as TriangleShape;
/// report a contact. internally this will be kept persistent, and contact reduction is done
resultOut.SetPersistentManifold(_manifold);
SphereTriangleDetector detector = new SphereTriangleDetector(sphere, triangle);
DiscreteCollisionDetectorInterface.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
input.MaximumDistanceSquared = 1e30f;//todo: tighter bounds
input.TransformA = bodyA.WorldTransform;
input.TransformB = bodyB.WorldTransform;
detector.GetClosestPoints(input, resultOut, null);
}
public override float CalculateTimeOfImpact(CollisionObject bodyA, CollisionObject bodyB, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
{
//not yet
return 1f;
}
public class CreateFunc : CollisionAlgorithmCreateFunction
{
public override CollisionAlgorithm CreateCollisionAlgorithm(CollisionAlgorithmConstructionInfo collisionAlgorithmConstructionInfo, CollisionObject bodyA, CollisionObject bodyB)
{
return new SphereTriangleCollisionAlgorithm(collisionAlgorithmConstructionInfo.Manifold, collisionAlgorithmConstructionInfo, bodyA, bodyB, IsSwapped);
}
}
#region IDisposable Members
public void Dispose()
{
if (_ownManifold)
if (_manifold != null)
Dispatcher.ReleaseManifold(_manifold);
}
#endregion
}
}

View File

@ -0,0 +1,214 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class SphereTriangleDetector : DiscreteCollisionDetectorInterface
{
private SphereShape _sphere;
private TriangleShape _triangle;
private const int MaxOverlap = 0;
public SphereTriangleDetector(SphereShape sphere, TriangleShape triangle)
{
this._sphere = sphere;
this._triangle = triangle;
}
public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw)
{
Matrix transformA = input.TransformA;
Matrix transformB = input.TransformB;
Vector3 point = new Vector3();
Vector3 normal = new Vector3();
Single timeOfImpact = 1.0f;
Single depth = 0.0f;
//move sphere into triangle space
Matrix sphereInTr = MathHelper.InverseTimes(transformB, transformA);
if (Collide(sphereInTr.Translation, point, normal, depth, timeOfImpact))
output.AddContactPoint(Vector3.TransformNormal(normal, transformB), Vector3.TransformNormal(point, transformB), depth);
}
/// <summary>
/// See also geometrictools.com
/// Basic idea: D = |p - (lo + t0*lv)| where t0 = lv . (p - lo) / lv . lv
/// </summary>
/// <param name="from"></param>
/// <param name="to"></param>
/// <param name="p"></param>
/// <param name="nearest"></param>
/// <returns></returns>
private float SegmentSquareDistance(Vector3 from, Vector3 to, Vector3 point, Vector3 nearest)
{
Vector3 diff = point - from;
Vector3 v = to - from;
float t = Vector3.Dot(v, diff);
if (t > 0)
{
float dotVV = Vector3.Dot(v, v);
if (t < dotVV)
{
t /= dotVV;
diff -= t * v;
}
else
{
t = 1;
diff -= v;
}
}
else
t = 0;
nearest = from + t * v;
return Vector3.Dot(diff, diff);
}
private bool Collide(Vector3 sphereCenter, Vector3 point, Vector3 resultNormal, float depth, float timeOfImpact)
{
Vector3[] vertices = _triangle.Vertices;
Vector3 c = sphereCenter;
float r = _sphere.Radius;
Vector3 delta = new Vector3();
Vector3 normal = Vector3.Cross(vertices[1] - vertices[0], vertices[2] - vertices[0]);
normal = Vector3.Normalize(normal);
Vector3 p1ToCentre = c - vertices[0];
float distanceFromPlane = Vector3.Dot(p1ToCentre, normal);
if (distanceFromPlane < 0)
{
//triangle facing the other way
distanceFromPlane *= -1;
normal *= -1;
}
float contactMargin = PersistentManifold.ContactBreakingThreshold;
bool isInsideContactPlane = distanceFromPlane < r + contactMargin;
bool isInsideShellPlane = distanceFromPlane < r;
float deltaDotNormal = Vector3.Dot(delta, normal);
if (!isInsideShellPlane && deltaDotNormal >= 0.0f)
return false;
// Check for contact / intersection
bool hasContact = false;
Vector3 contactPoint = new Vector3();
if (isInsideContactPlane)
{
if (FaceContains(c, vertices, normal))
{
// Inside the contact wedge - touches a point on the shell plane
hasContact = true;
contactPoint = c - normal * distanceFromPlane;
}
else
{
// Could be inside one of the contact capsules
float contactCapsuleRadiusSqr = (r + contactMargin) * (r + contactMargin);
Vector3 nearestOnEdge = new Vector3();
for (int i = 0; i < _triangle.EdgeCount; i++)
{
Vector3 pa, pb;
_triangle.GetEdge(i, out pa, out pb);
float distanceSqr = SegmentSquareDistance(pa, pb, c, nearestOnEdge);
if (distanceSqr < contactCapsuleRadiusSqr)
{
// Yep, we're inside a capsule
hasContact = true;
contactPoint = nearestOnEdge;
}
}
}
}
if (hasContact)
{
Vector3 contactToCentre = c - contactPoint;
float distanceSqr = contactToCentre.LengthSquared();
if (distanceSqr < (r - MaxOverlap) * (r - MaxOverlap))
{
float distance = (float)Math.Sqrt(distanceSqr);
resultNormal = contactToCentre;
resultNormal = Vector3.Normalize(resultNormal);
point = contactPoint;
depth = -(r - distance);
return true;
}
if (Vector3.Dot(delta, contactToCentre) >= 0.0f)
return false;
// Moving towards the contact point -> collision
point = contactPoint;
timeOfImpact = 0.0f;
return true;
}
return false;
}
private bool PointInTriangle(Vector3[] vertices, Vector3 normal, Vector3 p)
{
Vector3 p1 = vertices[0];
Vector3 p2 = vertices[1];
Vector3 p3 = vertices[2];
Vector3 edge1 = p2 - p1;
Vector3 edge2 = p3 - p2;
Vector3 edge3 = p1 - p3;
Vector3 p1ToP = p - p1;
Vector3 p2ToP = p - p2;
Vector3 p3ToP = p - p3;
Vector3 edge1Normal = Vector3.Cross(edge1, normal);
Vector3 edge2Normal = Vector3.Cross(edge2, normal);
Vector3 edge3Normal = Vector3.Cross(edge3, normal);
float r1, r2, r3;
r1 = Vector3.Dot(edge1Normal, p1ToP);
r2 = Vector3.Dot(edge2Normal, p2ToP);
r3 = Vector3.Dot(edge3Normal, p3ToP);
if ((r1 > 0 && r2 > 0 && r3 > 0) ||
(r1 <= 0 && r2 <= 0 && r3 <= 0))
return true;
return false;
}
private bool FaceContains(Vector3 p, Vector3[] vertices, Vector3 normal)
{
Vector3 lp = p;
Vector3 lnormal = normal;
return PointInTriangle(vertices, lnormal, lp);
}
}
}

View File

@ -0,0 +1,151 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public class UnionFind : IDisposable
{
private List<Element> _elements = new List<Element>();
public int ElementCount
{
get { return _elements.Count; }
}
public void SortIslands()
{
for (int i = 0; i < _elements.Count; i++)
{
_elements[i].ID = Find(i);
_elements[i].Size = i;
}
_elements.Sort(Sort);
}
private static int Sort(Element x, Element y)
{
if (x.ID < y.ID) return -1;
//else if (x.ID > y.ID) return 1;
else return 0;
}
public void Reset(int number)
{
Allocate(number);
for (int i = 0; i < number; i++)
{
Element element = new Element();
element.ID = i;
element.Size = 1;
_elements.Insert(i, element);
}
}
public bool IsRoot(int index)
{
return (_elements[index].Size == index);
}
public Element this[int index]
{
get { return _elements[index]; }
}
public void Allocate(int number)
{
//Does nothing
_elements = new List<Element>(number);
}
public bool Find(int i, int j)
{
return (Find(i) == Find(j));
}
public int Find(int i)
{
while (i != _elements[i].ID)
{
//Element element = _elements[i];
//element.ID = _elements[_elements[i].ID].ID;
_elements[i].ID = _elements[_elements[i].ID].ID;
i = _elements[i].ID;
}
return i;
}
public void Unite(int p, int q)
{
int i = Find(p), j = Find(q);
if (i == j)
return;
//weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
//if (_elements[i].Size < _elements[j].Size)
//{
// Element element = _elements[i];
// element.ID = j;
// _elements[i] = element;
// element = _elements[j];
// element.Size += _elements[i].Size;
// _elements[j] = element;
//}
//else
//{
// Element element = _elements[j];
// element.ID = i;
// _elements[j] = element;
// element = _elements[i];
// element.Size += _elements[j].Size;
// _elements[i] = element;
//}
_elements[i].ID = j;
_elements[j].Size += _elements[i].Size;
}
#region IDisposable Members
public void Dispose()
{
_elements.Clear();
}
#endregion
}
public class Element
{
private int _id;
private int _size;
public int ID { get { return _id; } set { _id = value; } }
public int Size { get { return _size; } set { _size = value; } }
}
}

View File

@ -0,0 +1,215 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// BUSimplex1to4 implements feature based and implicit simplex of up to 4 vertices (tetrahedron, triangle, line, vertex).
/// </summary>
public class BUSimplex1to4 : PolyhedralConvexShape
{
private int _numVertices = 0;
private Vector3[] _vertices = new Vector3[4];
public BUSimplex1to4() { }
public BUSimplex1to4(Vector3 pointA)
{
AddVertex(pointA);
}
public BUSimplex1to4(Vector3 pointA, Vector3 pointB)
{
AddVertex(pointA);
AddVertex(pointB);
}
public BUSimplex1to4(Vector3 pointA, Vector3 pointB, Vector3 pointC)
{
AddVertex(pointA);
AddVertex(pointB);
AddVertex(pointC);
}
public BUSimplex1to4(Vector3 pointA, Vector3 pointB, Vector3 pointC, Vector3 pointD)
{
AddVertex(pointA);
AddVertex(pointB);
AddVertex(pointC);
AddVertex(pointD);
}
protected Vector3[] Vertices { get { return _vertices; } set { _vertices = value; } }
public override int VertexCount
{
get
{
return _numVertices;
}
}
public override int EdgeCount
{
get
{
//euler formula, F-E+V = 2, so E = F+V-2
switch (_numVertices)
{
case 0: return 0;
case 1: return 0;
case 2: return 1;
case 3: return 3;
case 4: return 6;
}
return 0;
}
}
public override int PlaneCount
{
get
{
switch (_numVertices)
{
case 0:
return 0;
case 1:
return 0;
case 2:
return 0;
case 3:
return 2;
case 4:
return 4;
}
return 0;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Tetrahedral;
}
}
public override string Name
{
get
{
return "BUSimplex1to4";
}
}
public void AddVertex(Vector3 v)
{
_vertices[_numVertices++] = v;
}
public void Reset()
{
_numVertices = 0;
}
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
{
switch (_numVertices)
{
case 2:
pa = _vertices[0];
pb = _vertices[1];
return;
case 3:
switch (i)
{
case 0:
pa = _vertices[0];
pb = _vertices[1];
return;
case 1:
pa = _vertices[1];
pb = _vertices[2];
return;
case 2:
pa = _vertices[2];
pb = _vertices[0];
return;
}
break;
case 4:
switch (i)
{
case 0:
pa = _vertices[0];
pb = _vertices[1];
return;
case 1:
pa = _vertices[1];
pb = _vertices[2];
return;
case 2:
pa = _vertices[2];
pb = _vertices[0];
return;
case 3:
pa = _vertices[0];
pb = _vertices[3];
return;
case 4:
pa = _vertices[1];
pb = _vertices[3];
return;
case 5:
pa = _vertices[2];
pb = _vertices[3];
return;
}
break;
}
pa = new Vector3();
pb = new Vector3();
}
public override void GetVertex(int i, out Vector3 vtx)
{
vtx = _vertices[i];
}
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
{
planeNormal = new Vector3();
planeSupport = new Vector3();
}
public override bool IsInside(Vector3 pt, float tolerance)
{
return false;
}
}
}

View File

@ -0,0 +1,316 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class BoxShape : PolyhedralConvexShape
{
public BoxShape(Vector3 boxHalfExtents)
{
ImplicitShapeDimensions = boxHalfExtents;
}
public override int VertexCount
{
get
{
return 8;
}
}
public override int EdgeCount
{
get
{
return 12;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Box;
}
}
public override string Name
{
get
{
return "Box";
}
}
public override int PreferredPenetrationDirectionsCount
{
get
{
return 6;
}
}
public override int PlaneCount
{
get
{
return 6;
}
}
public Vector3 HalfExtents { get { return ImplicitShapeDimensions * LocalScaling; } }
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
{
int edgeVert0 = 0;
int edgeVert1 = 0;
switch (i)
{
case 0:
edgeVert0 = 0;
edgeVert1 = 1;
break;
case 1:
edgeVert0 = 0;
edgeVert1 = 2;
break;
case 2:
edgeVert0 = 1;
edgeVert1 = 3;
break;
case 3:
edgeVert0 = 2;
edgeVert1 = 3;
break;
case 4:
edgeVert0 = 0;
edgeVert1 = 4;
break;
case 5:
edgeVert0 = 1;
edgeVert1 = 5;
break;
case 6:
edgeVert0 = 2;
edgeVert1 = 6;
break;
case 7:
edgeVert0 = 3;
edgeVert1 = 7;
break;
case 8:
edgeVert0 = 4;
edgeVert1 = 5;
break;
case 9:
edgeVert0 = 4;
edgeVert1 = 6;
break;
case 10:
edgeVert0 = 5;
edgeVert1 = 7;
break;
case 11:
edgeVert0 = 6;
edgeVert1 = 7;
break;
default:
throw new BulletException();
}
GetVertex(edgeVert0, out pa);
GetVertex(edgeVert1, out pb);
}
public override void GetVertex(int i, out Vector3 vtx)
{
Vector3 halfExtents = HalfExtents;
vtx = new Vector3(
halfExtents.X * (1 - (i & 1)) - halfExtents.X * (i & 1),
halfExtents.Y * (1 - ((i & 2) >> 1)) - halfExtents.Y * ((i & 2) >> 1),
halfExtents.Z * (1 - ((i & 4) >> 2)) - halfExtents.Z * ((i & 4) >> 2));
}
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
{
//this plane might not be aligned...
Vector4 plane;
GetPlaneEquation(out plane, i);
planeNormal = new Vector3(plane.X, plane.Y, plane.Z);
planeSupport = LocalGetSupportingVertex(-planeNormal);
}
public override bool IsInside(Vector3 pt, float tolerance)
{
Vector3 halfExtents = HalfExtents;
//btScalar minDist = 2*tolerance;
bool result = (pt.X <= ( halfExtents.X + tolerance)) &&
(pt.X >= (-halfExtents.X - tolerance)) &&
(pt.Y <= ( halfExtents.Y + tolerance)) &&
(pt.Y >= (-halfExtents.Y - tolerance)) &&
(pt.Z <= ( halfExtents.Z + tolerance)) &&
(pt.Z >= (-halfExtents.Z - tolerance));
return result;
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 halfExtents = HalfExtents;
return new Vector3( vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
Vector3 halfExtents = HalfExtents;
Vector3 margin = new Vector3(Margin, Margin, Margin);
halfExtents -= margin;
return new Vector3( vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
Vector3 halfExtents = HalfExtents;
Vector3 margin = new Vector3(Margin, Margin, Margin);
halfExtents -= margin;
for (int i = 0; i < vectors.Length; i++)
{
Vector3 vec = vectors[i];
supportVerticesOut[i] = new Vector3(vec.X < 0.0f ? -halfExtents.X : halfExtents.X,
vec.Y < 0.0f ? -halfExtents.Y : halfExtents.Y,
vec.Z < 0.0f ? -halfExtents.Z : halfExtents.Z);
}
}
public virtual void GetPlaneEquation(out Vector4 plane, int i)
{
Vector3 halfExtents = HalfExtents;
switch (i)
{
case 0:
plane = new Vector4(1, 0, 0, 0);
plane.W = -halfExtents.X;
break;
case 1:
plane = new Vector4(-1, 0, 0, 0);
plane.W = -halfExtents.X;
break;
case 2:
plane = new Vector4(0, 1, 0, 0);
plane.W = -halfExtents.Y;
break;
case 3:
plane = new Vector4(0, -1, 0, 0);
plane.W = -halfExtents.Y;
break;
case 4:
plane = new Vector4(0, 0, 1, 0);
plane.W = -halfExtents.Z;
break;
case 5:
plane = new Vector4(0, 0, -1, 0);
plane.W = -halfExtents.Z;
break;
default:
throw new BulletException();
}
}
public override void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
{
switch (index)
{
case 0:
penetrationVector = new Vector3(1, 0, 0);
break;
case 1:
penetrationVector = new Vector3(-1, 0, 0);
break;
case 2:
penetrationVector = new Vector3(0, 1, 0);
break;
case 3:
penetrationVector = new Vector3(0, -1, 0);
break;
case 4:
penetrationVector = new Vector3(0, 0, 1);
break;
case 5:
penetrationVector = new Vector3(0, 0, -1);
break;
default:
throw new BulletException();
}
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 halfExtents = HalfExtents;
Matrix abs_b = MathHelper.Absolute(t);
Vector3 center = t.Translation;
Vector3 row1 = new Vector3(abs_b.M11, abs_b.M12, abs_b.M13);
Vector3 row2 = new Vector3(abs_b.M21, abs_b.M22, abs_b.M23);
Vector3 row3 = new Vector3(abs_b.M31, abs_b.M32, abs_b.M33);
Vector3 extent = new Vector3(Vector3.Dot(row1, halfExtents),
Vector3.Dot(row2, halfExtents),
Vector3.Dot(row3, halfExtents));
extent += new Vector3(Margin, Margin, Margin);
aabbMin = center - extent;
aabbMax = center + extent;
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
Vector3 halfExtents = HalfExtents;
float lx = 2f * (halfExtents.X);
float ly = 2f * (halfExtents.Y);
float lz = 2f * (halfExtents.Z);
inertia = new Vector3();
inertia.X = mass / (12.0f) * (ly * ly + lz * lz);
inertia.Y = mass / (12.0f) * (lx * lx + lz * lz);
inertia.Z = mass / (12.0f) * (lx * lx + ly * ly);
}
}
}

View File

@ -0,0 +1,83 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
class MyNodeOverlapCallback : INodeOverlapCallback
{
StridingMeshInterface _meshInterface;
ITriangleCallback _callback;
Vector3[] _triangle = new Vector3[3];
public MyNodeOverlapCallback(ITriangleCallback callback, StridingMeshInterface meshInterface)
{
_meshInterface = meshInterface;
_callback = callback;
}
public void ProcessNode(OptimizedBvhNode node)
{
List<Vector3> verts;
List<int> indicies;
int numtriangles;
_meshInterface.GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, node.SubPart);
Vector3 meshScaling = _meshInterface.Scaling;
for (int j = 0; j < 3; j++)
{
_triangle[j] = verts[indicies[j + node.TriangleIndex * 3]] * meshScaling;
}
_callback.ProcessTriangle(_triangle, node.SubPart, node.TriangleIndex);
_meshInterface.UnLockReadOnlyVertexBase(node.SubPart);
}
}
public class BvhTriangleMeshShape : TriangleMeshShape
{
OptimizedBvh _bvh = new OptimizedBvh();
public BvhTriangleMeshShape(StridingMeshInterface meshInterface) : base(meshInterface)
{
_bvh.Build(meshInterface);
}
public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
{
MyNodeOverlapCallback myNodeCallback = new MyNodeOverlapCallback(callback, MeshInterface);
_bvh.ReportAabbOverlappingNodex(myNodeCallback, aabbMin, aabbMax);
}
public override string Name
{
get
{
return "BvhTriangleMesh";
}
}
}
}

View File

@ -0,0 +1,148 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// CollisionShape provides generic interface for collidable objects
/// </summary>
public abstract class CollisionShape
{
//debugging support
private string _tempDebug;
public abstract string Name { get; }
public string ExtraDebugInfo { get { return _tempDebug; } set { _tempDebug = value; } }
public bool IsPolyhedral
{
get
{
return BroadphaseProxy.IsPolyhedral(ShapeType);
}
}
public bool IsConvex
{
get
{
return BroadphaseProxy.IsConvex(ShapeType);
}
}
public bool IsConcave
{
get
{
return BroadphaseProxy.IsConcave(ShapeType);
}
}
public bool IsCompound
{
get
{
return BroadphaseProxy.IsCompound(ShapeType);
}
}
//isInfinite is used to catch simulation error (aabb check)
public bool IsInfinite
{
get
{
return BroadphaseProxy.IsInfinite(ShapeType);
}
}
public abstract float Margin { get; set; }
public abstract Vector3 LocalScaling { get; set; }
public abstract BroadphaseNativeTypes ShapeType { get; }
public virtual void GetBoundingSphere(out Vector3 center, out float radius)
{
Matrix tr = Matrix.Identity;
Vector3 aabbMin, aabbMax;
GetAabb(tr, out aabbMin, out aabbMax);
radius = (aabbMax - aabbMin).Length() * 0.5f;
center = (aabbMin + aabbMax) * 0.5f;
}
public virtual float GetAngularMotionDisc()
{
Vector3 center;
float disc;
GetBoundingSphere(out center, out disc);
disc += center.Length();
return disc;
}
//calculateTemporalAabb calculates the enclosing aabb for the moving object over interval [0..timeStep)
//result is conservative
public void CalculateTemporalAabb(Matrix currentTransform, Vector3 linearVelocity, Vector3 angularVelocity, float timeStep, out Vector3 temporalAabbMin, out Vector3 temporalAabbMax)
{
//start with static aabb
GetAabb(currentTransform, out temporalAabbMin, out temporalAabbMax);
float temporalAabbMaxx = temporalAabbMax.X;
float temporalAabbMaxy = temporalAabbMax.Y;
float temporalAabbMaxz = temporalAabbMax.Z;
float temporalAabbMinx = temporalAabbMin.X;
float temporalAabbMiny = temporalAabbMin.Y;
float temporalAabbMinz = temporalAabbMin.Z;
// add linear motion
Vector3 linMotion = linearVelocity * timeStep;
//todo: simd would have a vector max/min operation, instead of per-element access
if (linMotion.X > 0)
temporalAabbMaxx += linMotion.X;
else
temporalAabbMinx += linMotion.X;
if (linMotion.Y > 0)
temporalAabbMaxy += linMotion.Y;
else
temporalAabbMiny += linMotion.Y;
if (linMotion.Z > 0)
temporalAabbMaxz += linMotion.Z;
else
temporalAabbMinz += linMotion.Z;
//add conservative angular motion
float angularMotion = angularVelocity.Length() * GetAngularMotionDisc() * timeStep;
Vector3 angularMotion3d = new Vector3(angularMotion, angularMotion, angularMotion);
temporalAabbMin = new Vector3(temporalAabbMinx, temporalAabbMiny, temporalAabbMinz);
temporalAabbMax = new Vector3(temporalAabbMaxx, temporalAabbMaxy, temporalAabbMaxz);
temporalAabbMin -= angularMotion3d;
temporalAabbMax += angularMotion3d;
}
public abstract void GetAabb(Matrix transform, out Vector3 aabbMin, out Vector3 aabbMax);
public abstract void CalculateLocalInertia(float mass, out Vector3 inertia);
}
}

View File

@ -0,0 +1,183 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// CompoundShape allows to store multiple other CollisionShapes
/// This allows for concave collision objects. This is more general then the Static Concave TriangleMeshShape.
/// </summary>
public class CompoundShape : CollisionShape
{
private List<Matrix> _childTransforms = new List<Matrix>();
private List<CollisionShape> _childShapes = new List<CollisionShape>();
private Vector3 _localAabbMin;
private Vector3 _localAabbMax;
private OptimizedBvh _aabbTree;
private float _collisionMargin;
private Vector3 _localScaling;
public CompoundShape()
{
_localAabbMin = new Vector3(1e30f, 1e30f, 1e30f);
_localAabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
_aabbTree = null;
_collisionMargin = 0f;
_localScaling = new Vector3(1f, 1f, 1f);
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 localHalfExtents = 0.5f * (_localAabbMax - _localAabbMin);
Vector3 localCenter = 0.5f * (_localAabbMax + _localAabbMin);
Matrix abs_b = MathHelper.Absolute(t);
Vector3 row1 = new Vector3(abs_b.M11, abs_b.M12, abs_b.M13);
Vector3 row2 = new Vector3(abs_b.M21, abs_b.M22, abs_b.M23);
Vector3 row3 = new Vector3(abs_b.M31, abs_b.M32, abs_b.M33);
Vector3 center = new Vector3(Vector3.Dot(row1, localCenter) + t.Translation.X,
Vector3.Dot(row2, localCenter) + t.Translation.Y,
Vector3.Dot(row3, localCenter) + t.Translation.Z);
Vector3 extent = new Vector3(Vector3.Dot(row1, localHalfExtents),
Vector3.Dot(row2, localHalfExtents),
Vector3.Dot(row3, localHalfExtents));
aabbMin = center - extent;
aabbMax = center + extent;
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Compound;
}
}
public override Vector3 LocalScaling
{
get
{
return _localScaling;
}
set
{
_localScaling = value;
}
}
public override string Name
{
get
{
return "Compound";
}
}
public override float Margin
{
get
{
return _collisionMargin;
}
set
{
_collisionMargin = value;
}
}
public int ChildShapeCount { get { return _childShapes.Count; } }
//this is optional, but should make collision queries faster, by culling non-overlapping nodes
public OptimizedBvh AabbTree { get { return _aabbTree; } }
public CollisionShape GetChildShape(int index)
{
return _childShapes[index];
}
public Matrix GetChildTransform(int index)
{
return _childTransforms[index];
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
//approximation: take the inertia from the aabb for now
Matrix ident = Matrix.Identity;
Vector3 aabbMin, aabbMax;
GetAabb(ident, out aabbMin, out aabbMax);
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
float lx = 2f * (halfExtents.X);
float ly = 2f * (halfExtents.Y);
float lz = 2f * (halfExtents.Z);
inertia = new Vector3();
inertia.X = mass / (12.0f) * (ly * ly + lz * lz);
inertia.Y = mass / (12.0f) * (lx * lx + lz * lz);
inertia.Z = mass / (12.0f) * (lx * lx + ly * ly);
}
public void AddChildShape(Matrix localTransform, CollisionShape shape)
{
_childTransforms.Add(localTransform);
_childShapes.Add(shape);
//extend the local aabbMin/aabbMax
Vector3 localAabbMin, localAabbMax;
shape.GetAabb(localTransform, out localAabbMin, out localAabbMax);
if (_localAabbMin.X > localAabbMin.X)
{
_localAabbMin.X = localAabbMin.X;
}
if (_localAabbMax.X < localAabbMax.X)
{
_localAabbMax.X = localAabbMax.X;
}
if (_localAabbMin.Y > localAabbMin.Y)
{
_localAabbMin.Y = localAabbMin.Y;
}
if (_localAabbMax.Y < localAabbMax.Y)
{
_localAabbMax.Y = localAabbMax.Y;
}
if (_localAabbMin.Z > localAabbMin.Z)
{
_localAabbMin.Z = localAabbMin.Z;
}
if (_localAabbMax.Z < localAabbMax.Z)
{
_localAabbMax.Z = localAabbMax.Z;
}
}
}
}

View File

@ -0,0 +1,55 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public abstract class ConcaveShape : CollisionShape
{
private float _collisionMargin;
public ConcaveShape() { }
public float CollisionMargin
{
get { return _collisionMargin; }
set { _collisionMargin = value; }
}
public override float Margin
{
get
{
return _collisionMargin;
}
set
{
_collisionMargin = value;
}
}
public abstract void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax);
}
}

View File

@ -0,0 +1,208 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// ConeShape implements a Cone shape, around the X axis
/// </summary>
public class ConeShapeX : ConeShape
{
public ConeShapeX(float radius, float height)
: base(radius, height)
{
ConeUpIndex = 0;
}
}
/// <summary>
/// ConeShape implements a Cone shape, around the Z axis
/// </summary>
public class ConeShapeZ : ConeShape
{
public ConeShapeZ(float radius, float height)
: base(radius, height)
{
ConeUpIndex = 2;
}
}
/// <summary>
/// ConeShape implements a Cone shape, around the Y axis
/// </summary>
public class ConeShape : ConvexShape
{
private float _sinAngle;
private float _radius;
private float _height;
private int[] _coneIndices = new int[3];
public ConeShape(float radius, float height)
{
_radius = radius;
_height = height;
ConeUpIndex = 1;
_sinAngle = (_radius / (float)Math.Sqrt(_radius * _radius + _height * _height));
}
public float Radius { get { return _radius; } }
public float Height { get { return _height; } }
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Cone;
}
}
public override string Name
{
get
{
return "Cone";
}
}
//choose upAxis index
public int ConeUpIndex
{
get { return _coneIndices[1]; }
set
{
switch (value)
{
case 0:
_coneIndices[0] = 1;
_coneIndices[1] = 0;
_coneIndices[2] = 2;
break;
case 1:
_coneIndices[0] = 0;
_coneIndices[1] = 1;
_coneIndices[2] = 2;
break;
case 2:
_coneIndices[0] = 0;
_coneIndices[1] = 2;
_coneIndices[2] = 1;
break;
default:
BulletDebug.Assert(false);
break;
}
}
}
private Vector3 ConeLocalSupport(Vector3 v)
{
float halfHeight = _height * 0.5f;
bool condition;
if (_coneIndices[1] == 0)
condition = v.X > v.Length() * _sinAngle;
else if (_coneIndices[1] == 1)
condition = v.Y > v.Length() * _sinAngle;
else
condition = v.Z > v.Length() * _sinAngle;
if (condition)
{
Vector3 tmp = new Vector3();
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], halfHeight);
return tmp;
}
else
{
float s = (float)Math.Sqrt(MathHelper.GetValueByIndex(v, _coneIndices[0]) * MathHelper.GetValueByIndex(v, _coneIndices[0])
+ MathHelper.GetValueByIndex(v, _coneIndices[2]) * MathHelper.GetValueByIndex(v, _coneIndices[2]));
if (s > MathHelper.Epsilon)
{
float d = _radius / s;
Vector3 tmp = new Vector3();
MathHelper.SetValueByIndex(ref tmp, _coneIndices[0], MathHelper.GetValueByIndex(v, _coneIndices[0]) * d);
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], -halfHeight);
MathHelper.SetValueByIndex(ref tmp, _coneIndices[2], MathHelper.GetValueByIndex(v, _coneIndices[2]) * d);
return tmp;
}
else
{
Vector3 tmp = new Vector3();
MathHelper.SetValueByIndex(ref tmp, _coneIndices[1], -halfHeight);
return tmp;
}
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
return ConeLocalSupport(vec);
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
supportVerticesOut[i] = ConeLocalSupport(vectors[i]);
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
Matrix identity = Matrix.Identity;
Vector3 aabbMin, aabbMax;
GetAabb(identity, out aabbMin, out aabbMax);
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
float margin = Margin;
float lx = 2f * (halfExtents.X + margin);
float ly = 2f * (halfExtents.Y + margin);
float lz = 2f * (halfExtents.Z + margin);
float x2 = lx * lx;
float y2 = ly * ly;
float z2 = lz * lz;
float scaledmass = mass * 0.08333333f;
inertia = scaledmass * (new Vector3(y2 + z2, x2 + z2, x2 + y2));
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex = ConeLocalSupport(vec);
if (Margin != 0)
{
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm = new Vector3(-1f, -1f, -1f);
}
vecnorm = Vector3.Normalize(vecnorm);
supVertex += Margin * vecnorm;
}
return supVertex;
}
}
}

View File

@ -0,0 +1,184 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// ConvexHullShape implements an implicit (getSupportingVertex) Convex Hull of a Point Cloud (vertices)
/// No connectivity is needed. localGetSupportingVertex iterates linearly though all vertices.
/// on modern hardware, due to cache coherency this isn't that bad. Complex algorithms tend to trash the cash.
/// (memory is much slower then the cpu)
/// </summary>
public class ConvexHullShape : PolyhedralConvexShape
{
private List<Vector3> _points = new List<Vector3>();
public ConvexHullShape() { }
public override int VertexCount
{
get
{
return _points.Count;
}
}
public override int EdgeCount
{
get
{
return _points.Count;
}
}
public override int PlaneCount
{
get
{
return 0;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.ConvexHull;
}
}
public override string Name
{
get
{
return "Convex";
}
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
if (Margin != 0)
{
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm=new Vector3(-1, -1, -1);
}
vecnorm = Vector3.Normalize(vecnorm);
supVertex += Margin * vecnorm;
}
return supVertex;
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec0)
{
Vector3 supVec = new Vector3();
float newDot, maxDot = -1e30f;
Vector3 vec = vec0;
float lenSqr = vec.LengthSquared();
if (lenSqr < 0.0001f)
{
vec = new Vector3(1, 0, 0);
}
else
{
float rlen = 1f / (float)Math.Sqrt(lenSqr);
vec *= rlen;
}
for (int i = 0; i < _points.Count; i++)
{
Vector3 vtx = _points[i] * LocalScaling;
newDot = Vector3.Dot(vec, vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
return supVec;
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
float newDot;
//use 'w' component of supportVerticesOut?
/*{
for (int i = 0; i < numVectors; i++)
{
supportVerticesOut[i][3] = -1e30f;
}
}*/
#warning Warning!
for (int i = 0; i < _points.Count; i++)
{
Vector3 vtx = _points[i] * LocalScaling;
for (int j = 0; j < vectors.Length; j++)
{
newDot = Vector3.Dot(vectors[j], vtx);
if (newDot > -1e30f)
{
//WARNING: don't swap next lines, the w component would get overwritten!
supportVerticesOut[j] = vtx;
//supportVerticesOut[j][3] = newDot;
#warning Warning!
}
}
}
}
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
{
int index0 = i % _points.Count;
int index1 = (i + 1) % _points.Count;
pa = _points[index0] * LocalScaling;
pb = _points[index1] * LocalScaling;
}
public override void GetVertex(int i, out Vector3 vtx)
{
vtx = _points[i] * LocalScaling;
}
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
{
planeNormal = new Vector3();
planeSupport = new Vector3();
BulletDebug.Assert(false);
}
public override bool IsInside(Vector3 pt, float tolerance)
{
BulletDebug.Assert(false);
return false;
}
}
}

View File

@ -0,0 +1,141 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// ConvexShape is an abstract shape interface.
/// The explicit part provides plane-equations, the implicit part provides GetClosestPoint interface.
/// used in combination with GJK or btConvexCast
/// </summary>
public abstract class ConvexShape : CollisionShape
{
private const int _maxPreferredPenetrationDirections = 10;
private const float _convexDistanceMargin = 0.04f;
private Vector3 _localScaling;
private Vector3 _implicitShapeDimensions;
private float _collisionMargin;
public ConvexShape()
: base()
{
_localScaling = Vector3.One;
_collisionMargin = ConvexDistanceMargin;
}
public static int MaxPreferredPenetrationDirections { get { return _maxPreferredPenetrationDirections; } }
public static float ConvexDistanceMargin { get { return _convexDistanceMargin; } }
public Vector3 ImplicitShapeDimensions { get { return _implicitShapeDimensions; } protected set { _implicitShapeDimensions = value; } }
public virtual int PreferredPenetrationDirectionsCount { get { return 0; } }
protected float CollisionMargin { get { return _collisionMargin; } set { _collisionMargin = value; } }
public virtual void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
{
penetrationVector = new Vector3();
BulletDebug.Assert(false);
}
public abstract Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec);
//notice that the vectors should be unit length
public abstract void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut);
/// <summary>
/// getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
/// </summary>
/// <param name="t"></param>
/// <param name="aabbMin"></param>
/// <param name="aabbMax"></param>
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
GetAabbSlow(t, out aabbMin, out aabbMax);
}
public override Vector3 LocalScaling
{
get
{
return _localScaling;
}
set
{
_localScaling = value;
}
}
public override float Margin
{
get
{
return _collisionMargin;
}
set
{
_collisionMargin = value;
}
}
public virtual Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
if (Margin != 0f)
{
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm = new Vector3(-1f, -1f, -1f);
}
vecnorm.Normalize();
supVertex += Margin * vecnorm;
}
return supVertex;
}
public virtual void GetAabbSlow(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
float margin = Margin;
aabbMax = new Vector3();
aabbMin = new Vector3();
for (int i = 0; i < 3; i++)
{
Vector3 vec = new Vector3(0f, 0f, 0f);
MathHelper.SetElement(ref vec, i, 1);
Vector3 sv = LocalGetSupportingVertex(Vector3.TransformNormal(vec, t));
Vector3 tmp = MathHelper.MatrixToVector(t, sv);
MathHelper.SetElement(ref aabbMax, i, MathHelper.GetElement(tmp, i) + margin);
MathHelper.SetElement(ref vec, i, -1f);
tmp = MathHelper.MatrixToVector(t, LocalGetSupportingVertex(Vector3.TransformNormal(vec, t)));
MathHelper.SetElement(ref aabbMin, i, MathHelper.GetElement(tmp, i) - margin);
}
}
}
}

View File

@ -0,0 +1,185 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// ConvexTriangleMeshShape is a convex hull of a triangle mesh. If you just have a point cloud, you can use ConvexHullShape instead.
/// It uses the StridingMeshInterface instead of a point cloud. This can avoid the duplication of the triangle mesh data.
/// </summary>
public class ConvexTriangleMeshShape : PolyhedralConvexShape
{
private StridingMeshInterface _stridingMesh;
public ConvexTriangleMeshShape(StridingMeshInterface meshInterface)
{
_stridingMesh = meshInterface;
}
public StridingMeshInterface getStridingMesh()
{
return _stridingMesh;
}
public override int VertexCount
{
get
{
return 0;
}
}
public override int EdgeCount
{
get
{
return 0;
}
}
public override int PlaneCount
{
get
{
return 0;
}
}
public override Vector3 LocalScaling
{
get
{
return base.LocalScaling;
}
set
{
_stridingMesh.Scaling = value;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.ConvexTriangleMesh;
}
}
public override string Name
{
get
{
return "ConvexTrimesh";
}
}
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
{
pa = new Vector3();
pb = new Vector3();
BulletDebug.Assert(false);
}
public override void GetVertex(int i, out Vector3 vtx)
{
vtx = new Vector3();
BulletDebug.Assert(false);
}
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
{
planeNormal = new Vector3();
planeSupport = new Vector3();
BulletDebug.Assert(false);
}
public override bool IsInside(Vector3 pt, float tolerance)
{
BulletDebug.Assert(false);
return false;
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
if (Margin != 0)
{
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm = new Vector3(-1, -1, -1);
}
vecnorm = Vector3.Normalize(vecnorm);
supVertex += Margin * vecnorm;
}
return supVertex;
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec0)
{
Vector3 supVec = new Vector3();
Vector3 vec = vec0;
float lenSqr = vec.LengthSquared();
if (lenSqr < 0.0001f)
{
vec = new Vector3(1, 0, 0);
}
else
{
float rlen = 1f / (float)Math.Sqrt(lenSqr);
vec *= rlen;
}
LocalSupportVertexCallback supportCallback = new LocalSupportVertexCallback(vec);
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
_stridingMesh.InternalProcessAllTriangles(supportCallback, -aabbMax, aabbMax);
supVec = supportCallback.SupportVertexLocal;
return supVec;
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
//use 'w' component of supportVerticesOut?
/*{
for (int i = 0; i < numVectors; i++)
{
supportVerticesOut[i][3] = -1e30f;
}
}*/
for (int j = 0; j < vectors.Length; j++)
{
Vector3 vec = vectors[j];
LocalSupportVertexCallback supportCallback = new LocalSupportVertexCallback(vec);
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
_stridingMesh.InternalProcessAllTriangles(supportCallback, -aabbMax, aabbMax);
supportVerticesOut[j] = supportCallback.SupportVertexLocal;
}
}
}
}

View File

@ -0,0 +1,136 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// implements cylinder shape interface
/// </summary>
public class CylinderShape : BoxShape
{
public CylinderShape(Vector3 halfExtents)
: base(halfExtents)
{
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Cylinder;
}
}
public virtual int UpAxis
{
get
{
return 1;
}
}
public virtual float Radius
{
get
{
return HalfExtents.Z;
}
}
//debugging
public override string Name
{
get
{
return "CylinderY";
}
}
//getAabb's default implementation is brute force, expected derived classes to implement a fast dedicated version
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
GetAabbSlow(t, out aabbMin, out aabbMax);
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
return CylinderLocalSupportY(HalfExtents, vec);
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
{
supportVerticesOut[i] = CylinderLocalSupportY(HalfExtents, vectors[i]);
}
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex;
supVertex = LocalGetSupportingVertexWithoutMargin(vec);
if (Margin != 0)
{
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm=new Vector3(-1, -1, -1);
}
vecnorm = Vector3.Normalize(vecnorm);
supVertex += Margin * vecnorm;
}
return supVertex;
}
private Vector3 CylinderLocalSupportY(Vector3 halfExtents, Vector3 v)
{
float radius = halfExtents.X;
float halfHeight = halfExtents.Y;
Vector3 tmp = new Vector3();
float d;
float s = (float)Math.Sqrt(v.X * v.X + v.Z * v.Z);
if (s != 0)
{
d = radius / s;
tmp.X = v.X * d;
tmp.Y = v.Y < 0 ? -halfHeight : halfHeight;
tmp.Z = v.Z * d;
return tmp;
}
else
{
tmp.X = radius;
tmp.Y = v.Y < 0 ? -halfHeight : halfHeight;
tmp.Z = 0;
return tmp;
}
}
}
}

View File

@ -0,0 +1,100 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CylinderShapeX : CylinderShape
{
public CylinderShapeX(Vector3 halfExtents)
: base(halfExtents) { }
public override int UpAxis
{
get
{
return 0;
}
}
public override float Radius
{
get
{
return HalfExtents.Y;
}
}
//debugging
public override string Name
{
get
{
return "CylinderX";
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
return CylinderLocalSupportX(HalfExtents, vec);
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
{
supportVerticesOut[i] = CylinderLocalSupportX(HalfExtents, vectors[i]);
}
}
private Vector3 CylinderLocalSupportX(Vector3 halfExtents, Vector3 v)
{
//mapping depends on how cylinder local orientation is
// extents of the cylinder is: X,Y is for radius, and Z for height
float radius = halfExtents.Y;
float halfHeight = halfExtents.X;
Vector3 tmp = new Vector3();
float d;
float s = (float)Math.Sqrt(v.Y * v.Y + v.Z * v.Z);
if (s != 0)
{
d = radius / s;
tmp.Y = v.Y * d;
tmp.X = v.X < 0 ? -halfHeight : halfHeight;
tmp.Z = v.Z * d;
return tmp;
}
else
{
tmp.Y = radius;
tmp.X = v.X < 0 ? -halfHeight : halfHeight;
tmp.Z = 0;
return tmp;
}
}
}
}

View File

@ -0,0 +1,100 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class CylinderShapeZ : CylinderShape
{
public CylinderShapeZ(Vector3 halfExtents)
: base(halfExtents) { }
public override int UpAxis
{
get
{
return 2;
}
}
public override float Radius
{
get
{
return HalfExtents.X;
}
}
//debugging
public override string Name
{
get
{
return "CylinderZ";
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
return CylinderLocalSupportZ(HalfExtents, vec);
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
{
supportVerticesOut[i] = CylinderLocalSupportZ(HalfExtents, vectors[i]);
}
}
Vector3 CylinderLocalSupportZ(Vector3 halfExtents, Vector3 v)
{
//mapping depends on how cylinder local orientation is
// extents of the cylinder is: X,Y is for radius, and Z for height
float radius = halfExtents.X;
float halfHeight = halfExtents.Z;
Vector3 tmp = new Vector3();
float d;
float s = (float)Math.Sqrt(v.X * v.X + v.Y * v.Y);
if (s != 0)
{
d = radius / s;
tmp.X = v.X * d;
tmp.Z = v.Z < 0 ? -halfHeight : halfHeight;
tmp.Y = v.Y * d;
return tmp;
}
else
{
tmp.X = radius;
tmp.Z = v.Z < 0 ? -halfHeight : halfHeight;
tmp.Y = 0;
return tmp;
}
}
}
}

View File

@ -0,0 +1,80 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
using System.Diagnostics;
namespace XnaDevRu.BulletX
{
public class EmptyShape : ConcaveShape
{
private Vector3 _localScaling;
public override string Name
{
get
{
return "Empty";
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Empty;
}
}
public override Vector3 LocalScaling
{
get
{
return _localScaling;
}
set
{
_localScaling = value;
}
}
public override void ProcessAllTriangles(ITriangleCallback callback, Microsoft.Xna.Framework.Vector3 aabbMin, Microsoft.Xna.Framework.Vector3 aabbMax)
{
throw new Exception("The method or operation is not implemented.");
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 margin = new Vector3(Margin, Margin, Margin);
aabbMin = t.Translation - margin;
aabbMax = t.Translation + margin;
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
inertia = new Vector3();
BulletDebug.Assert(false);
}
}
}

View File

@ -0,0 +1,55 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class FilteredCallback : ITriangleIndexCallback
{
private ITriangleCallback _callback;
private Vector3 _aabbMin;
private Vector3 _aabbMax;
public FilteredCallback(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
{
_callback = callback;
_aabbMin = aabbMin;
_aabbMax = aabbMax;
}
public ITriangleCallback TriangleCallback { get { return _callback; } set { _callback = value; } }
public Vector3 AabbMin { get { return _aabbMin; } set { _aabbMin = value; } }
public Vector3 AabbMax { get { return _aabbMax; } set { _aabbMax = value; } }
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
{
if (MathHelper.TestTriangleAgainstAabb2(triangle, _aabbMin, _aabbMax))
{
//check aabb in triangle-space, before doing this
_callback.ProcessTriangle(triangle, partId, triangleIndex);
}
}
}
}

View File

@ -0,0 +1,33 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public interface ITriangleIndexCallback
{
void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex);
}
}

View File

@ -0,0 +1,58 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class LocalSupportVertexCallback : ITriangleIndexCallback
{
private Vector3 _supportVertexLocal;
private float _maxDot;
private Vector3 _supportVecLocal;
public LocalSupportVertexCallback(Vector3 supportVecLocal)
{
_supportVertexLocal = new Vector3();
_maxDot = -1e30f;
_supportVecLocal = supportVecLocal;
}
public float MaxDot { get { return _maxDot; } set { _maxDot = value; } }
public Vector3 SupportVertexLocal { get { return _supportVecLocal; } set { _supportVecLocal = value; } }
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
{
for (int i = 0; i < 3; i++)
{
float dot = Vector3.Dot(_supportVecLocal, triangle[i]);
if (dot > _maxDot)
{
_maxDot = dot;
_supportVertexLocal = triangle[i];
}
}
}
}
}

View File

@ -0,0 +1,99 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// MinkowskiSumShape represents implicit (getSupportingVertex) based minkowski sum of two convex implicit shapes.
/// </summary>
public class MinkowskiSumShape : ConvexShape
{
private Matrix _transformA;
private Matrix _transformB;
private ConvexShape _shapeA;
private ConvexShape _shapeB;
public MinkowskiSumShape(ConvexShape shapeA, ConvexShape shapeB)
{
_shapeA = shapeA;
_shapeB = shapeB;
_transformA = Matrix.Identity;
_transformB = Matrix.Identity;
}
public Matrix TransformA { get { return _transformA; } set { _transformA = value; } }
public Matrix TransformB { get { return _transformB; } set { _transformB = value; } }
public ConvexShape ShapeA { get { return _shapeA; } }
public ConvexShape ShapeB { get { return _shapeB; } }
public override float Margin
{
get
{
return _shapeA.Margin + _shapeB.Margin;
}
set
{
base.Margin = value;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.MinkowskiDifference;
}
}
public override string Name
{
get
{
return "MinkowskiSum";
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
Vector3 supVertexA = MathHelper.MatrixToVector(_transformA, _shapeA.LocalGetSupportingVertexWithoutMargin(Vector3.TransformNormal(vec, _transformA)));
Vector3 supVertexB = MathHelper.MatrixToVector(_transformB, _shapeB.LocalGetSupportingVertexWithoutMargin(Vector3.TransformNormal(vec, _transformB)));
return supVertexA + supVertexB;
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
supportVerticesOut[i] = LocalGetSupportingVertexWithoutMargin(vectors[i]);
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
inertia = new Vector3();
BulletDebug.Assert(false);
}
}
}

View File

@ -0,0 +1,154 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// MultiSphereShape represents implicit convex hull of a collection of spheres (using getSupportingVertex)
/// </summary>
public class MultiSphereShape : ConvexShape
{
private const int _maxNumSpheres = 5;
private Vector3[] _localPositions = new Vector3[MaxNumSpheres];
private float[] _radi = new float[MaxNumSpheres];
private Vector3 _inertiaHalfExtents;
private int m_numSpheres;
public MultiSphereShape(Vector3 inertiaHalfExtents, Vector3[] positions, float[] radi, int numSpheres)
{
_inertiaHalfExtents = inertiaHalfExtents;
float startMargin = 1e30f;
m_numSpheres = numSpheres;
for (int i = 0; i < m_numSpheres; i++)
{
_localPositions[i] = positions[i];
_radi[i] = radi[i];
if (radi[i] < startMargin)
startMargin = radi[i];
}
Margin = startMargin;
}
public static int MaxNumSpheres { get { return _maxNumSpheres; } }
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.MultiSphere;
}
}
public override string Name
{
get
{
return "MultiSphere";
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vecA)
{
Vector3 supVec = new Vector3();
float maxDot = -1e30f;
Vector3 vec = vecA;
float lenSqr = vec.LengthSquared();
if (lenSqr < 0.0001f)
{
vec = new Vector3(1, 0, 0);
}
else
{
float rlen = 1f / (float)Math.Sqrt(lenSqr);
vec *= rlen;
}
Vector3 vtx;
float newDot;
for (int i = 0; i < m_numSpheres; i++)
{
vtx = _localPositions[i] + vec * LocalScaling * _radi[i] - vec * Margin;
newDot = Vector3.Dot(vec, vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
return supVec;
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int j = 0; j < vectors.Length; j++)
{
float maxDot = -1e30f;
Vector3 vtx;
float newDot;
for (int i = 0; i < m_numSpheres; i++)
{
vtx = _localPositions[i] + vectors[j] * LocalScaling * _radi[i] - vectors[j] * Margin;
newDot = Vector3.Dot(vectors[j], vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supportVerticesOut[j] = vtx;
}
}
}
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
//as an approximation, take the inertia of the box that bounds the spheres
Matrix ident = Matrix.Identity;
Vector3 halfExtents = _inertiaHalfExtents;
float margin = ConvexDistanceMargin;
float lx = 2f * (halfExtents.X + margin);
float ly = 2f * (halfExtents.Y + margin);
float lz = 2f * (halfExtents.Z + margin);
float x2 = lx * lx;
float y2 = ly * ly;
float z2 = lz * lz;
float scaledmass = mass * 0.08333333f;
inertia = new Vector3();
inertia.X = scaledmass * (y2 + z2);
inertia.Y = scaledmass * (x2 + z2);
inertia.Z = scaledmass * (x2 + y2);
}
}
}

View File

@ -0,0 +1,32 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
namespace XnaDevRu.BulletX
{
public interface INodeOverlapCallback
{
void ProcessNode(OptimizedBvhNode node);
}
}

View File

@ -0,0 +1,293 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// OptimizedBvh store an AABB tree that can be quickly traversed on CPU (and SPU,GPU in future)
/// </summary>
public class OptimizedBvh
{
private static int _maxIterations = 0;
private OptimizedBvhNode _rootNode;
private OptimizedBvhNode[] _contiguousNodes;
private int _curNodeIndex;
private List<OptimizedBvhNode> _leafNodes = new List<OptimizedBvhNode>();
public OptimizedBvh() { }
public void Build(StridingMeshInterface triangles)
{
NodeTriangleCallback callback = new NodeTriangleCallback(_leafNodes);
Vector3 aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
triangles.InternalProcessAllTriangles(callback, aabbMin, aabbMax);
//now we have an array of leafnodes in m_leafNodes
_contiguousNodes = new OptimizedBvhNode[2 * _leafNodes.Count];
for (int i = 0; i < _contiguousNodes.Length; i++)
_contiguousNodes[i] = new OptimizedBvhNode();
_curNodeIndex = 0;
_rootNode = BuildTree(_leafNodes, 0, _leafNodes.Count);
}
public OptimizedBvhNode BuildTree(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex)
{
OptimizedBvhNode internalNode;
int splitAxis, splitIndex, i;
int numIndices = endIndex - startIndex;
int curIndex = _curNodeIndex;
if (numIndices <= 0)
throw new BulletException();
if (numIndices == 1)
{
_contiguousNodes[_curNodeIndex++] = leafNodes[startIndex];
//return new (&m_contiguousNodes[m_curNodeIndex++]) btOptimizedBvhNode(leafNodes[startIndex]);
return leafNodes[startIndex];
}
//calculate Best Splitting Axis and where to split it. Sort the incoming 'leafNodes' array within range 'startIndex/endIndex'.
splitAxis = CalculateSplittingAxis(leafNodes, startIndex, endIndex);
splitIndex = SortAndCalculateSplittingIndex(leafNodes, startIndex, endIndex, splitAxis);
internalNode = _contiguousNodes[_curNodeIndex++];
internalNode.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
internalNode.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
for (i = startIndex; i < endIndex; i++)
{
internalNode.AabbMax = MathHelper.SetMax(internalNode.AabbMax, leafNodes[i].AabbMax);
internalNode.AabbMin = MathHelper.SetMin(internalNode.AabbMin, leafNodes[i].AabbMin);
}
//internalNode->m_escapeIndex;
internalNode.LeftChild = BuildTree(leafNodes, startIndex, splitIndex);
internalNode.RightChild = BuildTree(leafNodes, splitIndex, endIndex);
internalNode.EscapeIndex = _curNodeIndex - curIndex;
return internalNode;
}
public int CalculateSplittingAxis(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex)
{
Vector3 means = new Vector3();
Vector3 variance = new Vector3();
int numIndices = endIndex - startIndex;
for (int i = startIndex; i < endIndex; i++)
{
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
means += center;
}
means *= (1f / (float)numIndices);
for (int i = startIndex; i < endIndex; i++)
{
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
Vector3 diff2 = center - means;
diff2 = diff2 * diff2;
variance += diff2;
}
variance *= (1f / ((float)numIndices - 1));
return MathHelper.MaxAxis(variance);
}
public int SortAndCalculateSplittingIndex(List<OptimizedBvhNode> leafNodes, int startIndex, int endIndex, int splitAxis)
{
int splitIndex = startIndex;
int numIndices = endIndex - startIndex;
float splitValue;
Vector3 means = new Vector3();
for (int i = startIndex; i < endIndex; i++)
{
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
means += center;
}
means *= (1f / (float)numIndices);
if (splitAxis == 0)
splitValue = means.X;
else if (splitAxis == 1)
splitValue = means.Y;
else if (splitAxis == 2)
splitValue = means.Z;
else
throw new ArgumentException();
//sort leafNodes so all values larger then splitValue comes first, and smaller values start from 'splitIndex'.
for (int i = startIndex; i < endIndex; i++)
{
Vector3 center = 0.5f * (leafNodes[i].AabbMax + leafNodes[i].AabbMin);
float centerSplit;
if (splitAxis == 0)
centerSplit = means.X;
else if (splitAxis == 1)
centerSplit = means.Y;
else if (splitAxis == 2)
centerSplit = means.Z;
else
throw new ArgumentException();
if (centerSplit > splitValue)
{
//swap
OptimizedBvhNode tmp = leafNodes[i];
leafNodes[i] = leafNodes[splitIndex];
leafNodes[splitIndex] = tmp;
splitIndex++;
}
}
if ((splitIndex == startIndex) || (splitIndex == (endIndex - 1)))
{
splitIndex = startIndex + (numIndices >> 1);
}
return splitIndex;
}
public void WalkTree(OptimizedBvhNode rootNode, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
{
bool isLeafNode, aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
if (aabbOverlap)
{
isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
if (isLeafNode)
{
nodeCallback.ProcessNode(rootNode);
}
else
{
WalkTree(rootNode.LeftChild, nodeCallback, aabbMin, aabbMax);
WalkTree(rootNode.RightChild, nodeCallback, aabbMin, aabbMax);
}
}
}
public void WalkStacklessTree(OptimizedBvhNode[] rootNodeArray, INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
{
int escapeIndex, curIndex = 0;
int walkIterations = 0;
bool aabbOverlap, isLeafNode;
int rootNodeIndex = 0;
OptimizedBvhNode rootNode = rootNodeArray[rootNodeIndex];
while (curIndex < _curNodeIndex)
{
//catch bugs in tree data
if (walkIterations >= _curNodeIndex)
throw new BulletException();
walkIterations++;
aabbOverlap = MathHelper.TestAabbAgainstAabb2(aabbMin, aabbMax, rootNode.AabbMin, rootNode.AabbMax);
isLeafNode = (rootNode.LeftChild == null && rootNode.RightChild == null);
if (isLeafNode && aabbOverlap)
{
nodeCallback.ProcessNode(rootNode);
}
if (aabbOverlap || isLeafNode)
{
rootNodeIndex++; // this
curIndex++;
if (rootNodeIndex < rootNodeArray.Length)
rootNode = rootNodeArray[rootNodeIndex];
}
else
{
escapeIndex = rootNode.EscapeIndex;
rootNodeIndex += escapeIndex; // and this
curIndex += escapeIndex;
if (rootNodeIndex < rootNodeArray.Length)
rootNode = rootNodeArray[rootNodeIndex];
}
}
if (_maxIterations < walkIterations)
_maxIterations = walkIterations;
}
public void ReportAabbOverlappingNodex(INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax)
{
//either choose recursive traversal (walkTree) or stackless (walkStacklessTree)
//walkTree(m_rootNode1,nodeCallback,aabbMin,aabbMax);
//WalkStacklessTree(_rootNode, nodeCallback, aabbMin, aabbMax);
WalkStacklessTree(_contiguousNodes, nodeCallback, aabbMin, aabbMax);
}
public void ReportSphereOverlappingNodex(INodeOverlapCallback nodeCallback, Vector3 aabbMin, Vector3 aabbMax) { }
}
public class NodeTriangleCallback : ITriangleIndexCallback
{
private List<OptimizedBvhNode> _triangleNodes;
public NodeTriangleCallback(List<OptimizedBvhNode> triangleNodes)
{
_triangleNodes = triangleNodes;
}
public List<OptimizedBvhNode> TriangleNodes { get { return _triangleNodes; } set { _triangleNodes = value; } }
public void ProcessTriangleIndex(Vector3[] triangle, int partId, int triangleIndex)
{
OptimizedBvhNode node = new OptimizedBvhNode();
node.AabbMin = new Vector3(1e30f, 1e30f, 1e30f);
node.AabbMax = new Vector3(-1e30f, -1e30f, -1e30f);
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[0]);
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[0]);
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[1]);
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[1]);
node.AabbMin = MathHelper.SetMin(node.AabbMin, triangle[2]);
node.AabbMax = MathHelper.SetMax(node.AabbMax, triangle[2]);
node.EscapeIndex = -1;
node.LeftChild = null;
node.RightChild = null;
//for child nodes
node.SubPart = partId;
node.TriangleIndex = triangleIndex;
_triangleNodes.Add(node);
}
}
}

View File

@ -0,0 +1,63 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// OptimizedBvhNode contains both internal and leaf node information.
/// It hasn't been optimized yet for storage. Some obvious optimizations are:
/// Removal of the pointers (can already be done, they are not used for traversal)
/// and storing aabbmin/max as quantized integers.
/// 'subpart' doesn't need an integer either. It allows to re-use graphics triangle
/// meshes stored in a non-uniform way (like batches/subparts of triangle-fans
/// </summary>
public class OptimizedBvhNode
{
private Vector3 _aabbMin;
private Vector3 _aabbMax;
//these 2 pointers are obsolete, the stackless traversal just uses the escape index
private OptimizedBvhNode _leftChild;
private OptimizedBvhNode _rightChild;
private int _escapeIndex;
//for child nodes
private int _subPart;
private int _triangleIndex;
public Vector3 AabbMin { get { return _aabbMin; } set { _aabbMin = value; } }
public Vector3 AabbMax { get { return _aabbMax; } set { _aabbMax = value; } }
public OptimizedBvhNode LeftChild { get { return _leftChild; } set { _leftChild = value; } }
public OptimizedBvhNode RightChild { get { return _rightChild; } set { _rightChild = value; } }
public int EscapeIndex { get { return _escapeIndex; } set { _escapeIndex = value; } }
public int SubPart { get { return _subPart; } set { _subPart = value; } }
public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
}
}

View File

@ -0,0 +1,133 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public abstract class PolyhedralConvexShape : ConvexShape
{
public PolyhedralConvexShape()
{
//m_optionalHull = null;
}
public abstract int VertexCount { get; }
public abstract int EdgeCount { get; }
public abstract int PlaneCount { get; }
public abstract void GetEdge(int i, out Vector3 pointA, out Vector3 pointB);
public abstract void GetVertex(int i, out Vector3 vertex);
public abstract void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i);
// abstract int getIndex(int i);
public abstract bool IsInside(Vector3 point, float tolerance);
// optional Hull is for optional Separating Axis Test Hull collision detection, see Hull.cpp
//public class Hull m_optionalHull;
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
Vector3 supVec = new Vector3();
float maxDot = -1e30f;
float lenSqr = vec.LengthSquared();
if (lenSqr < 0.0001f)
{
vec = new Vector3(1, 0, 0);
}
else
{
float rlen = 1f / (float)Math.Sqrt(lenSqr);
vec *= rlen;
}
Vector3 vtx;
float newDot;
for (int i = 0; i < VertexCount; i++)
{
GetVertex(i, out vtx);
newDot = Vector3.Dot(vec, vtx);
if (newDot > maxDot)
{
maxDot = newDot;
supVec = vtx;
}
}
return supVec;
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
#warning Think about this
/*Vector3 vtx;
float newDot;
for (int i = 0; i < vectors.Length; i++)
{
supportVerticesOut[i][3] = -1e30f;
}
for (int j = 0; j < vectors.Length; j++)
{
Vector3 vec = vectors[j];
for (int i = 0; i < getNumVertices(); i++)
{
getVertex(i, out vtx);
newDot = Vector3.Dot(vec,vtx);
if (newDot > supportVerticesOut[j][3])
{
//WARNING: don't swap next lines, the w component would get overwritten!
supportVerticesOut[j] = vtx;
supportVerticesOut[j][3] = newDot;
}
}
}*/
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
//not yet, return box inertia
float margin = Margin;
Matrix ident = Matrix.Identity;
Vector3 aabbMin, aabbMax;
GetAabb(ident, out aabbMin, out aabbMax);
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
float lx = 2f * (halfExtents.X + margin);
float ly = 2f * (halfExtents.Y + margin);
float lz = 2f * (halfExtents.Z + margin);
float x2 = lx * lx;
float y2 = ly * ly;
float z2 = lz * lz;
float scaledmass = mass * 0.08333333f;
inertia = scaledmass * (new Vector3(y2 + z2, x2 + z2, x2 + y2));
}
}
}

View File

@ -0,0 +1,116 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// btSphereShape implements an implicit (getSupportingVertex) Sphere
/// </summary>
public class SphereShape : ConvexShape
{
public SphereShape(float radius)
: base()
{
Vector3 temp = ImplicitShapeDimensions;
temp.X = radius;
ImplicitShapeDimensions = temp;
}
public float Radius { get { return ImplicitShapeDimensions.X; } }
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Sphere;
}
}
public override string Name
{
get
{
return "Sphere";
}
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
return new Vector3();
}
/// <summary>
/// to improve gjk behaviour, use radius+margin as the full margin, so never get into the penetration case
/// this means, non-uniform scaling is not supported anymore
/// </summary>
public override float Margin
{
get
{
return LocalScaling.X * Radius + base.Margin;
}
set
{
base.Margin = value;
}
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
if (supportVerticesOut != null)
for (int i = 0; i < supportVerticesOut.Length; i++)
supportVerticesOut[i] = new Vector3();
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
float elem = 0.4f * mass * Margin * Margin;
inertia = new Vector3(elem, elem, elem);
}
public override Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supVertex = LocalGetSupportingVertexWithoutMargin(vec);
Vector3 vecnorm = vec;
if (vecnorm.LengthSquared() < (MathHelper.Epsilon * MathHelper.Epsilon))
{
vecnorm = new Vector3(-1f, -1f, -1f);
}
vecnorm.Normalize();
supVertex += Margin * vecnorm;
return supVertex;
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 center = t.Translation;
Vector3 extent = new Vector3(Margin, Margin, Margin);
aabbMin = center - extent;
aabbMax = center + extent;
}
}
}

View File

@ -0,0 +1,124 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class StaticPlaneShape : ConcaveShape
{
private Vector3 _localAabbMin;
private Vector3 _localAabbMax;
private Vector3 _planeNormal;
private float _planeConstant;
private Vector3 _localScaling;
public StaticPlaneShape(Vector3 planeNormal, float planeConstant)
{
_planeNormal = planeNormal;
_planeConstant = planeConstant;
_localScaling = new Vector3();
}
protected Vector3 LocalAabbMin { get { return _localAabbMin; } set { _localAabbMin = value; } }
protected Vector3 LocalAabbMax { get { return _localAabbMax; } set { _localAabbMax = value; } }
protected Vector3 PlaneNormal { get { return _planeNormal; } set { _planeNormal = value; } }
protected float PlaneConstant { get { return _planeConstant; } set { _planeConstant = value; } }
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.StaticPlane;
}
}
public override Vector3 LocalScaling
{
get
{
return _localScaling;
}
set
{
_localScaling = value;
}
}
public override string Name
{
get
{
return "StaticPlane";
}
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 infvec = new Vector3(1e30f, 1e30f, 1e30f);
Vector3 center = _planeNormal * _planeConstant;
aabbMin = center + infvec * _planeNormal;
aabbMax = aabbMin;
MathHelper.SetMin(ref aabbMin, center - infvec * _planeNormal);
MathHelper.SetMax(ref aabbMax, center - infvec * _planeNormal);
aabbMin = new Vector3(-1e30f, -1e30f, -1e30f);
aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
//moving concave objects not supported
inertia = new Vector3();
}
public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax) {
Vector3 halfExtents = (aabbMax - aabbMin) * 0.5f;
float radius = halfExtents.Length();
Vector3 center = (aabbMax + aabbMin) * 0.5f;
//this is where the triangles are generated, given AABB and plane equation (normal/constant)
Vector3 tangentDir0 = new Vector3(), tangentDir1 = new Vector3();
//tangentDir0/tangentDir1 can be precalculated
MathHelper.PlaneSpace1(_planeNormal, ref tangentDir0, ref tangentDir1);
Vector3 projectedCenter = center - (Vector3.Dot(_planeNormal, center) - _planeConstant) * _planeNormal;
Vector3[] triangle = new Vector3[3];
triangle[0] = projectedCenter + tangentDir0 * radius + tangentDir1 * radius;
triangle[1] = projectedCenter + tangentDir0 * radius - tangentDir1 * radius;
triangle[2] = projectedCenter - tangentDir0 * radius - tangentDir1 * radius;
callback.ProcessTriangle(triangle, 0, 0);
triangle[0] = projectedCenter - tangentDir0 * radius - tangentDir1 * radius;
triangle[1] = projectedCenter - tangentDir0 * radius + tangentDir1 * radius;
triangle[2] = projectedCenter + tangentDir0 * radius + tangentDir1 * radius;
callback.ProcessTriangle(triangle, 0, 1);
}
}
}

View File

@ -0,0 +1,115 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// PHY_ScalarType enumerates possible scalar types.
/// See the StridingMeshInterface for its use
/// </summary>
public enum PHY_ScalarType
{
PHY_FLOAT,
PHY_DOUBLE,
PHY_INTEGER,
PHY_SHORT,
PHY_FIXEDPOINT88
}
/// <summary>
/// StridingMeshInterface is the interface class for high performance access to triangle meshes
/// It allows for sharing graphics and collision meshes. Also it provides locking/unlocking of graphics meshes that are in gpu memory.
/// </summary>
public abstract class StridingMeshInterface
{
protected Vector3 _scaling;
public StridingMeshInterface()
{
_scaling = new Vector3(1f,1f,1f);
}
public void InternalProcessAllTriangles(ITriangleIndexCallback callback, Vector3 aabbMin, Vector3 aabbMax)
{
int numtotalphysicsverts = 0;
int numtriangles, gfxindex;
int part, graphicssubparts = SubPartsCount();
Vector3[] triangle = new Vector3[3];
List<Vector3> verts;
List<int> indicies;
Vector3 meshScaling = Scaling;
//if the number of parts is big, the performance might drop due to the innerloop switch on indextype
for (part = 0; part < graphicssubparts; part++)
{
GetLockedReadOnlyVertexIndexBase(out verts, out indicies, out numtriangles, part);
numtotalphysicsverts += numtriangles * 3; //upper bound
for (gfxindex = 0; gfxindex < numtriangles; gfxindex++)
{
triangle[0] = verts[indicies[gfxindex * 3 + 0]];
triangle[1] = verts[indicies[gfxindex * 3 + 1]];
triangle[2] = verts[indicies[gfxindex * 3 + 2]];
callback.ProcessTriangleIndex(triangle, part, gfxindex);
}
UnLockReadOnlyVertexBase(part);
}
}
// get read and write access to a subpart of a triangle mesh
// this subpart has a continuous array of vertices and indices
// in this way the mesh can be handled as chunks of memory with striding
// very similar to OpenGL vertexarray support
// make a call to unLockVertexBase when the read and write access is finished
public abstract void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart);
public abstract void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart);
// unLockVertexBase finishes the access to a subpart of the triangle mesh
// make a call to unLockVertexBase when the read and write access (using getLockedVertexIndexBase) is finished
public abstract void UnLockVertexBase(int subpart);
public abstract void UnLockReadOnlyVertexBase(int subpart);
// getNumSubParts returns the number of seperate subparts
// each subpart has a continuous array of vertices and indices
public abstract int SubPartsCount();
public abstract void PreallocateVertices(int numverts);
public abstract void PreallocateIndices(int numindices);
public Vector3 Scaling
{
get { return _scaling; }
set { _scaling = value; }
}
}
}

View File

@ -0,0 +1,67 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
internal class SupportVertexCallback : ITriangleCallback
{
private Vector3 _supportVertexLocal;
private Matrix _worldTransform;
private float _maxDot;
private Vector3 _supportVecLocal;
public SupportVertexCallback(Vector3 supportVecWorld, Matrix trans)
{
_supportVertexLocal = new Vector3();
_worldTransform = trans;
_maxDot = -1e30f;
_supportVecLocal = Vector3.TransformNormal(supportVecWorld, _worldTransform);
}
public Matrix WorldTransform { get { return _worldTransform; } set { _worldTransform = value; } }
public float MaxDot { get { return _maxDot; } set { _maxDot = value; } }
public Vector3 SupportVectorLocal { get { return _supportVecLocal; } set { _supportVecLocal = value; } }
public Vector3 SupportVertexLocal { get { return _supportVertexLocal; } }
public Vector3 SupportVertexWorldSpace { get { return MathHelper.MatrixToVector(_worldTransform, _supportVertexLocal); } }
#region ITriangleCallback Members
public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex)
{
for (int i = 0; i < 3; i++)
{
float dot = Vector3.Dot(_supportVecLocal, triangle[i]);
if (dot > _maxDot)
{
_maxDot = dot;
_supportVertexLocal = triangle[i];
}
}
}
#endregion
}
}

View File

@ -0,0 +1,80 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class Triangle
{
private Vector3 _vertexA;
private Vector3 _vertexB;
private Vector3 _vertexC;
private int _partId;
private int _triangleIndex;
public Vector3 VertexA { get { return _vertexA; } set { _vertexA = value; } }
public Vector3 VertexB { get { return _vertexB; } set { _vertexB = value; } }
public Vector3 VertexC { get { return _vertexC; } set { _vertexC = value; } }
public int PartId { get { return _partId; } set { _partId = value; } }
public int TriangleIndex { get { return _triangleIndex; } set { _triangleIndex = value; } }
}
/// <summary>
/// example usage of this class:
/// TriangleBuffer triBuf;
/// concaveShape.processAllTriangles(triBuf, out aabbMin, out aabbMax);
/// for (int i = 0; i < triBuf.getNumTriangles(); i++)
/// {
/// Triangle tri = triBuf.getTriangle(i);
/// //do something useful here with the triangle
/// }
/// </summary>
public class TriangleBuffer : ITriangleCallback
{
private List<Triangle> _triangleBuffer = new List<Triangle>();
public int TriangleCount { get { return _triangleBuffer.Count; } }
public Triangle this[int index] { get { return _triangleBuffer[index]; } }
public void ClearBuffer()
{
_triangleBuffer.Clear();
}
#region ITriangleCallback Members
public void ProcessTriangle(Vector3[] triangle, int partID, int triangleIndex)
{
Triangle tri = new Triangle();
tri.VertexA = triangle[0];
tri.VertexB = triangle[1];
tri.VertexC = triangle[2];
tri.PartId = partID;
tri.TriangleIndex = triangleIndex;
_triangleBuffer.Add(tri);
}
#endregion
}
}

View File

@ -0,0 +1,33 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public interface ITriangleCallback
{
void ProcessTriangle(Vector3[] triangle, int partId, int triangleIndex);
}
}

View File

@ -0,0 +1,136 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// IndexedMesh indexes into existing vertex and index arrays, in a similar way OpenGL glDrawElements
/// instead of the number of indices, we pass the number of triangles
/// </summary>
public struct IndexedMesh
{
private int _numTriangles;
private int[] _triangleIndexBase;
private int _triangleIndexStride;
private int _numVertices;
private Vector3[] _vertexBase;
private int _vertexStride;
public IndexedMesh(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
{
_numTriangles = numTriangleIndices;
_triangleIndexBase = triangleIndexBase;
_triangleIndexStride = triangleIndexStride;
_vertexBase = vertexBase;
_numVertices = numVertices;
_vertexStride = vertexStride;
}
public IndexedMesh(int[] triangleIndexBase, Vector3[] vertexBase)
{
_numTriangles = triangleIndexBase.Length;
_triangleIndexBase = triangleIndexBase;
_triangleIndexStride = 32;
_vertexBase = vertexBase;
_numVertices = vertexBase.Length;
_vertexStride = 24;
}
public int TriangleCount { get { return _numTriangles; } set { _numTriangles = value; } }
public int[] TriangleIndexBase { get { return _triangleIndexBase; } set { _triangleIndexBase = value; } }
public int TriangleIndexStride { get { return _triangleIndexStride; } set { _triangleIndexStride = value; } }
public int VertexCount { get { return _numVertices; } set { _numVertices = value; } }
public Vector3[] VertexBase { get { return _vertexBase; } set { _vertexBase = value; } }
public int VertexStride { get { return _vertexStride; } set { _vertexStride = value; } }
}
/// <summary>
/// TriangleIndexVertexArray allows to use multiple meshes, by indexing into existing triangle/index arrays.
/// Additional meshes can be added using addIndexedMesh
/// </summary>
public class TriangleIndexVertexArray : StridingMeshInterface
{
List<IndexedMesh> _indexedMeshes = new List<IndexedMesh>();
public TriangleIndexVertexArray() { }
public TriangleIndexVertexArray(int numTriangleIndices, int[] triangleIndexBase, int triangleIndexStride, int numVertices, Vector3[] vertexBase, int vertexStride)
{
IndexedMesh mesh = new IndexedMesh();
mesh.TriangleCount = numTriangleIndices;
mesh.TriangleIndexBase = triangleIndexBase;
mesh.TriangleIndexStride = triangleIndexStride;
mesh.VertexBase = vertexBase;
mesh.VertexCount = numVertices;
mesh.VertexStride = vertexStride;
AddIndexedMesh(mesh);
}
public TriangleIndexVertexArray(int[] triangleIndexBase, Vector3[] vertexBase)
: this(triangleIndexBase.Length, triangleIndexBase, 32, vertexBase.Length, vertexBase, 24) { }
public void AddIndexedMesh(IndexedMesh indexedMesh)
{
_indexedMeshes.Add(indexedMesh);
}
public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
{
throw new Exception("The method or operation is not implemented.");
}
public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
{
throw new Exception("The method or operation is not implemented.");
}
public override void UnLockVertexBase(int subpart)
{
throw new Exception("The method or operation is not implemented.");
}
public override void UnLockReadOnlyVertexBase(int subpart)
{
throw new Exception("The method or operation is not implemented.");
}
public override int SubPartsCount()
{
return _indexedMeshes.Count;
}
public override void PreallocateVertices(int numverts)
{
throw new Exception("The method or operation is not implemented.");
}
public override void PreallocateIndices(int numindices)
{
throw new Exception("The method or operation is not implemented.");
}
}
}

View File

@ -0,0 +1,102 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
class TriangleMesh : StridingMeshInterface
{
int _numTriangles;
List<Vector3> _verts;
public TriangleMesh()
{
_numTriangles = 0;
_verts = new List<Vector3>();
}
void AddTriangle(Vector3 vertex0, Vector3 vertex1, Vector3 vertex2)
{
_verts.Add(vertex0);
_verts.Add(vertex1);
_verts.Add(vertex2);
_numTriangles++;
}
public override void GetLockedVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
{
verts = new List<Vector3>();
for (int i = 0; i < 3; i++)
{
verts.Add(_verts[subpart * 3 + i]);
}
indicies = new List<int>();
indicies.Add(0);
indicies.Add(1);
indicies.Add(2);
numfaces = 1;
}
public override void GetLockedReadOnlyVertexIndexBase(out List<Vector3> verts, out List<int> indicies, out int numfaces, int subpart)
{
verts = new List<Vector3>();
for (int i = 0; i < 3; i++)
{
verts.Add(_verts[subpart * 3 + i]);
}
indicies = new List<int>();
indicies.Add(0);
indicies.Add(1);
indicies.Add(2);
numfaces = 1;
}
public override void UnLockVertexBase(int subpart)
{
}
public override void UnLockReadOnlyVertexBase(int subpart)
{
}
public override int SubPartsCount()
{
return _numTriangles;
}
public override void PreallocateVertices(int numverts)
{
}
public override void PreallocateIndices(int numindices)
{
}
}
}

View File

@ -0,0 +1,160 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// Concave triangle mesh. Uses an interface to access the triangles to allow for sharing graphics/physics triangles.
/// </summary>
public class TriangleMeshShape : ConcaveShape
{
private StridingMeshInterface _meshInterface;
private Vector3 _localAabbMin;
private Vector3 _localAabbMax;
public TriangleMeshShape(StridingMeshInterface meshInterface)
{
this._meshInterface = meshInterface;
RecalcLocalAabb();
}
protected StridingMeshInterface MeshInterface { get { return _meshInterface; } set { _meshInterface = value; } }
protected Vector3 LocalAabbMin { get { return _localAabbMin; } set { _localAabbMin = value; } }
protected Vector3 LocalAabbMax { get { return _localAabbMax; } set { _localAabbMax = value; } }
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.TriangleMesh;
}
}
public override Vector3 LocalScaling
{
get
{
return _meshInterface.Scaling;
}
set
{
_meshInterface.Scaling = value;
}
}
public override string Name
{
get
{
return "TriangleMesh";
}
}
public void RecalcLocalAabb()
{
{
Vector3 vec = new Vector3();
vec.X = 1f;
Vector3 tmp = LocalGetSupportingVertex(vec);
_localAabbMax.X = tmp.X + CollisionMargin;
vec.X = -1f;
tmp = LocalGetSupportingVertex(vec);
_localAabbMin.X = tmp.X - CollisionMargin;
}
{
Vector3 vec = new Vector3();
vec.Y = 1f;
Vector3 tmp = LocalGetSupportingVertex(vec);
_localAabbMax.Y = tmp.Y + CollisionMargin;
vec.Y = -1f;
tmp = LocalGetSupportingVertex(vec);
_localAabbMin.Y = tmp.Y - CollisionMargin;
}
{
Vector3 vec = new Vector3();
vec.Z = 1f;
Vector3 tmp = LocalGetSupportingVertex(vec);
_localAabbMax.Z = tmp.Z + CollisionMargin;
vec.Z = -1f;
tmp = LocalGetSupportingVertex(vec);
_localAabbMin.Z = tmp.Z - CollisionMargin;
}
}
public override void ProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
{
LocalProcessAllTriangles(callback, aabbMax, aabbMax);
}
protected void LocalProcessAllTriangles(ITriangleCallback callback, Vector3 aabbMin, Vector3 aabbMax)
{
FilteredCallback filterCallback = new FilteredCallback(callback, aabbMin, aabbMax);
_meshInterface.InternalProcessAllTriangles(filterCallback, aabbMin, aabbMax);
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
Vector3 localHalfExtents = 0.5f * (_localAabbMax - _localAabbMin);
Vector3 localCenter = 0.5f * (_localAabbMax + _localAabbMin);
Matrix abs_b = MathHelper.Absolute(t);
Vector3 center = MathHelper.MatrixToVector(t, localCenter);
Vector3 extent = new Vector3(Vector3.Dot(new Vector3(abs_b.M11, abs_b.M12, abs_b.M13), localHalfExtents),
Vector3.Dot(new Vector3(abs_b.M21, abs_b.M22, abs_b.M23), localHalfExtents),
Vector3.Dot(new Vector3(abs_b.M31, abs_b.M32, abs_b.M33), localHalfExtents));
extent += new Vector3(Margin, Margin, Margin);
aabbMin = center - extent;
aabbMax = center + extent;
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
inertia = new Vector3();
//moving concave objects not supported
BulletDebug.Assert(false);
}
public virtual Vector3 LocalGetSupportingVertex(Vector3 vec)
{
Vector3 supportVertex;
Matrix ident = Matrix.Identity;
SupportVertexCallback supportCallback = new SupportVertexCallback(vec, ident);
Vector3 aabbMax = new Vector3(1e30f, 1e30f, 1e30f);
LocalProcessAllTriangles(supportCallback, -aabbMax, aabbMax);
supportVertex = supportCallback.SupportVertexLocal;
return supportVertex;
}
public virtual Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
BulletDebug.Assert(false);
return LocalGetSupportingVertex(vec);
}
}
}

View File

@ -0,0 +1,187 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class TriangleShape : PolyhedralConvexShape
{
private Vector3[] _vertices = new Vector3[3];
public TriangleShape(Vector3 pointA, Vector3 pointB, Vector3 pointC)
{
_vertices[0] = pointA;
_vertices[1] = pointB;
_vertices[2] = pointC;
}
public override int PreferredPenetrationDirectionsCount
{
get
{
return 2;
}
}
public Vector3[] Vertices
{
get
{
return _vertices;
}
}
public override int VertexCount
{
get
{
return 3;
}
}
public override int EdgeCount
{
get
{
return 3;
}
}
public override int PlaneCount
{
get
{
return 1;
}
}
public override BroadphaseNativeTypes ShapeType
{
get
{
return BroadphaseNativeTypes.Triangle;
}
}
public override string Name
{
get
{
return "Triangle";
}
}
public override void GetPreferredPenetrationDirection(int index, out Vector3 penetrationVector)
{
CalculateNormal(out penetrationVector);
if (index != 0)
penetrationVector *= -1f;
}
public virtual void GetPlaneEquation(int i, out Vector3 planeNormal, out Vector3 planeSupport)
{
CalculateNormal(out planeNormal);
planeSupport = _vertices[0];
}
public void CalculateNormal(out Vector3 normal)
{
normal = Vector3.Normalize(Vector3.Cross(_vertices[1] - _vertices[0], _vertices[2] - _vertices[0]));
}
public override Vector3 LocalGetSupportingVertexWithoutMargin(Vector3 vec)
{
Vector3 dots = new Vector3(Vector3.Dot(vec, _vertices[0]), Vector3.Dot(vec, _vertices[1]), Vector3.Dot(vec, _vertices[2]));
return _vertices[MathHelper.MaxAxis(dots)];
}
public override void BatchedUnitVectorGetSupportingVertexWithoutMargin(Vector3[] vectors, Vector3[] supportVerticesOut)
{
for (int i = 0; i < vectors.Length; i++)
{
Vector3 dir = vectors[i];
Vector3 dots = new Vector3(Vector3.Dot(dir, _vertices[0]), Vector3.Dot(dir, _vertices[1]), Vector3.Dot(dir, _vertices[2]));
supportVerticesOut[i] = _vertices[MathHelper.MaxAxis(dots)];
}
}
public override void CalculateLocalInertia(float mass, out Vector3 inertia)
{
inertia = new Vector3();
BulletDebug.Assert(false);
}
public override void GetEdge(int i, out Vector3 pa, out Vector3 pb)
{
GetVertex(i, out pa);
GetVertex((i + 1) % 3, out pb);
}
public override void GetAabb(Matrix t, out Vector3 aabbMin, out Vector3 aabbMax)
{
GetAabbSlow(t, out aabbMin, out aabbMax);
}
public override void GetVertex(int i, out Vector3 vtx)
{
vtx = _vertices[i];
}
public override void GetPlane(out Vector3 planeNormal, out Vector3 planeSupport, int i)
{
GetPlaneEquation(i, out planeNormal, out planeSupport);
}
public override bool IsInside(Vector3 pt, float tolerance)
{
Vector3 normal;
CalculateNormal(out normal);
//distance to plane
float dist = Vector3.Dot(pt, normal);
float planeconst = Vector3.Dot(_vertices[0], normal);
dist -= planeconst;
if (dist >= -tolerance && dist <= tolerance)
{
//inside check on edge-planes
int i;
for (i = 0; i < 3; i++)
{
Vector3 pa, pb;
GetEdge(i, out pa, out pb);
Vector3 edge = pb - pa;
Vector3 edgeNormal = Vector3.Cross(edge, normal);
edgeNormal = Vector3.Normalize(edgeNormal);
float distance = Vector3.Dot(pt, edgeNormal);
float edgeConst = Vector3.Dot(pa, edgeNormal);
distance -= edgeConst;
if (distance < -tolerance)
return false;
}
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,199 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// ContinuousConvexCollision implements angular and linear time of impact for convex objects.
/// Based on Brian Mirtich's Conservative Advancement idea (PhD thesis).
/// Algorithm operates in worldspace, in order to keep inbetween motion globally consistent.
/// It uses GJK at the moment. Future improvement would use minkowski sum / supporting vertex, merging innerloops
/// </summary>
public class ContinuousConvexCollision : IConvexCast
{
/// <summary>
/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
/// You don't want your game ever to lock-up.
/// </summary>
private const int MaxIterations = 1000;
private ISimplexSolver _simplexSolver;
private IConvexPenetrationDepthSolver _penetrationDepthSolver;
private ConvexShape _convexA;
private ConvexShape _convexB;
public ContinuousConvexCollision(ConvexShape convexA, ConvexShape convexB,
ISimplexSolver simplexSolver, IConvexPenetrationDepthSolver penetrationDepthSolver)
{
_simplexSolver = simplexSolver;
_penetrationDepthSolver = penetrationDepthSolver;
_convexA = convexA;
_convexB = convexB;
}
public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result)
{
_simplexSolver.Reset();
// compute linear and angular velocity for this interval, to interpolate
Vector3 linVelA = new Vector3(), angVelA = new Vector3(), linVelB = new Vector3(), angVelB = new Vector3();
TransformUtil.CalculateVelocity(fromA, toA, 1f, ref linVelA, ref angVelA);
TransformUtil.CalculateVelocity(fromB, toB, 1f, ref linVelB, ref angVelB);
float boundingRadiusA = _convexA.GetAngularMotionDisc();
float boundingRadiusB = _convexB.GetAngularMotionDisc();
float maxAngularProjectedVelocity = angVelA.Length() * boundingRadiusA +
angVelB.Length() * boundingRadiusB;
float radius = 0.001f;
float lambda = 0f;
Vector3 v = new Vector3(1f, 0f, 0f);
int maxIter = MaxIterations;
Vector3 n = new Vector3();
bool hasResult = false;
Vector3 c;
float lastLambda = lambda;
//float epsilon = 0.001f;
int numIter = 0;
//first solution, using GJK
Matrix identityTrans = Matrix.Identity;
SphereShape raySphere = new SphereShape(0f);
raySphere.Margin=0f;
//result.drawCoordSystem(sphereTr);
PointCollector pointCollector1 = new PointCollector();
GjkPairDetector gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver);
GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
//we don't use margins during CCD
gjk.setIgnoreMargin(true);
input.TransformA = fromA;
input.TransformB = fromB;
DiscreteCollisionDetectorInterface.Result r = (DiscreteCollisionDetectorInterface.Result)pointCollector1;
gjk.GetClosestPoints(input, r, null);
hasResult = pointCollector1.HasResult;
c = pointCollector1.PointInWorld;
if (hasResult)
{
float dist;
dist = pointCollector1.Distance;
n = pointCollector1.NormalOnBInWorld;
//not close enough
while (dist > radius)
{
numIter++;
if (numIter > maxIter)
return false; //todo: report a failure
float dLambda = 0f;
//calculate safe moving fraction from distance / (linear+rotational velocity)
//float clippedDist = GEN_min(angularConservativeRadius,dist);
//float clippedDist = dist;
float projectedLinearVelocity = Vector3.Dot(linVelB - linVelA, n);
dLambda = dist / (projectedLinearVelocity + maxAngularProjectedVelocity);
lambda = lambda + dLambda;
if (lambda > 1f) return false;
if (lambda < 0f) return false;
//todo: next check with relative epsilon
if (lambda <= lastLambda)
break;
lastLambda = lambda;
//interpolate to next lambda
Matrix interpolatedTransA = new Matrix(), interpolatedTransB = new Matrix(), relativeTrans;
TransformUtil.IntegrateTransform(fromA, linVelA, angVelA, lambda, ref interpolatedTransA);
TransformUtil.IntegrateTransform(fromB, linVelB, angVelB, lambda, ref interpolatedTransB);
relativeTrans = MathHelper.InverseTimes(interpolatedTransB, interpolatedTransA);
result.DebugDraw(lambda);
PointCollector pointCollector = new PointCollector();
gjk = new GjkPairDetector(_convexA, _convexB, (VoronoiSimplexSolver)_simplexSolver, _penetrationDepthSolver);
input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
input.TransformA = interpolatedTransA;
input.TransformB = interpolatedTransB;
// !!!!!!!!!!
r = (DiscreteCollisionDetectorInterface.Result)pointCollector1;
gjk.GetClosestPoints(input, r, null);
if (pointCollector.HasResult)
{
if (pointCollector.Distance < 0f)
{
//degenerate ?!
result.Fraction = lastLambda;
result.Normal = n;
return true;
}
c = pointCollector.PointInWorld;
dist = pointCollector.Distance;
}
else
{
//??
return false;
}
}
result.Fraction = lambda;
result.Normal = n;
return true;
}
return false;
}
}
}

View File

@ -0,0 +1,73 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// CastResult stores the closest result
/// alternatively, add a callback method to decide about closest/all results
/// </summary>
public class CastResult
{
private Vector3 _normal;
private float _fraction;
private Matrix _hitTransformA;
private Matrix _hitTransformB;
private IDebugDraw _debugDrawer;
public CastResult()
{
_fraction = 1e30f;
}
public Vector3 Normal { get { return _normal; } set { _normal = value; } }
public float Fraction { get { return _fraction; } set { _fraction = value; } }
public Matrix HitTransformA { get { return _hitTransformA; } set { _hitTransformA = value; } }
public Matrix HitTransformB { get { return _hitTransformB; } set { _hitTransformB = value; } }
public IDebugDraw DebugDrawer { get { return _debugDrawer; } set { _debugDrawer = value; } }
public virtual void DebugDraw(float fraction) { }
public virtual void DrawCoordSystem(Matrix trans) { }
}
/// <summary>
/// ConvexCast is an interface for Casting
/// </summary>
public interface IConvexCast
{
/// <summary>
/// cast a convex against another convex object
/// </summary>
/// <param name="fromA"></param>
/// <param name="toA"></param>
/// <param name="fromB"></param>
/// <param name="toB"></param>
/// <param name="result"></param>
/// <returns></returns>
bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result);
}
}

View File

@ -0,0 +1,117 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public abstract class DiscreteCollisionDetectorInterface
{
public abstract class Result
{
public abstract void SetShapeIdentifiers(int partIdA, int indexA, int partIdB, int indexB);
public abstract void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth);
}
public class ClosestPointInput
{
private float _maximumDistanceSquared;
private Matrix _transformA, _transformB;
#region Properties
public Matrix TransformB
{
get { return _transformB; }
set { _transformB = value; }
}
public Matrix TransformA
{
get { return _transformA; }
set { _transformA = value; }
}
public float MaximumDistanceSquared
{
get { return _maximumDistanceSquared; }
set { _maximumDistanceSquared = value; }
}
#endregion
public ClosestPointInput()
{
_maximumDistanceSquared = 1e30f;
}
}
public abstract void GetClosestPoints(ClosestPointInput input, Result output, IDebugDraw debugDraw);
}
public class StorageResult : DiscreteCollisionDetectorInterface.Result
{
private Vector3 _closestPointInB;
private Vector3 _normalOnSurfaceB;
private float _distance; //negative means penetration !
#region Properties
public float Distance
{
get { return _distance; }
set { _distance = value; }
}
public Vector3 NormalOnSurfaceB
{
get { return _normalOnSurfaceB; }
set { _normalOnSurfaceB = value; }
}
public Vector3 ClosestPointInB
{
get { return _closestPointInB; }
set { _closestPointInB = value; }
}
#endregion
public StorageResult()
{
_distance = 1e30f;
}
public override void AddContactPoint(Vector3 normalOnBInWorld, Vector3 pointInWorld, float depth)
{
if (depth < _distance)
{
_normalOnSurfaceB = normalOnBInWorld;
_closestPointInB = pointInWorld;
_distance = depth;
}
}
public override void SetShapeIdentifiers(int partId0, int index0, int partId1, int index1)
{
throw new Exception("The method or operation is not implemented.");
}
}
}

View File

@ -0,0 +1,176 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// GjkConvexCast performs a raycast on a convex object using support mapping.
/// </summary>
public class GjkConvexCast : IConvexCast
{
private VoronoiSimplexSolver _simplexSolver;
private ConvexShape _convexA, _convexB;
public GjkConvexCast(ConvexShape convexShapeA, ConvexShape convexShapeB, VoronoiSimplexSolver solver)
{
_simplexSolver = solver;
_convexA = convexShapeA;
_convexB = convexShapeB;
}
#region IConvexCast Members
/// <summary>
/// cast a convex against another convex object
/// </summary>
/// <param name="fromA"></param>
/// <param name="toA"></param>
/// <param name="fromB"></param>
/// <param name="toB"></param>
/// <param name="result"></param>
/// <returns></returns>
public bool CalcTimeOfImpact(Matrix fromA, Matrix toA, Matrix fromB, Matrix toB, CastResult result)
{
MinkowskiSumShape combined = new MinkowskiSumShape(_convexA, _convexB);
Matrix rayFromLocalA = MathHelper.InvertMatrix(fromA) * fromB;
Matrix rayToLocalA = MathHelper.InvertMatrix(toA) * toB;
Matrix transformA = fromA;
Matrix transformB = fromB;
transformA.Translation = new Vector3(0, 0, 0);
transformB.Translation = new Vector3(0, 0, 0);
combined.TransformA = transformA;
combined.TransformB = transformB;
float radius = 0.01f;
float lambda = 0;
Vector3 s = rayFromLocalA.Translation;
Vector3 r = rayToLocalA.Translation - rayFromLocalA.Translation;
Vector3 x = s;
Vector3 n = new Vector3();
Vector3 c = new Vector3();
bool hasResult = false;
float lastLambda = lambda;
IConvexPenetrationDepthSolver penSolver = null;
Matrix identityTransform = Matrix.Identity;
SphereShape raySphere = new SphereShape(0.0f);
raySphere.Margin=0.0f;
Matrix sphereTransform = Matrix.Identity;
sphereTransform.Translation = rayFromLocalA.Translation;
result.DrawCoordSystem(sphereTransform);
{
PointCollector pointCollector = new PointCollector();
GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver);
GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
input.TransformA = sphereTransform;
input.TransformB = identityTransform;
gjk.GetClosestPoints(input, pointCollector, null);
hasResult = pointCollector.HasResult;
c = pointCollector.PointInWorld;
n = pointCollector.NormalOnBInWorld;
}
if (hasResult)
{
float dist = (c - x).Length();
if (dist < radius)
{
lastLambda = 1.0f;
}
while (dist > radius)
{
n = x - c;
float dot = Vector3.Dot(n, r);
if (dot >= -(MathHelper.Epsilon * MathHelper.Epsilon)) return false;
lambda = lambda - Vector3.Distance(n, n) / dot;
if (lambda <= lastLambda) break;
lastLambda = lambda;
x = s + lambda * r;
sphereTransform.Translation = x;
result.DrawCoordSystem(sphereTransform);
PointCollector pointCollector = new PointCollector();
GjkPairDetector gjk = new GjkPairDetector(raySphere, combined, _simplexSolver, penSolver);
GjkPairDetector.ClosestPointInput input = new DiscreteCollisionDetectorInterface.ClosestPointInput();
input.TransformA = sphereTransform;
input.TransformB = identityTransform;
gjk.GetClosestPoints(input, pointCollector, null);
if (pointCollector.HasResult)
{
if (pointCollector.Distance < 0.0f)
{
result.Fraction = lastLambda;
result.Normal = n;
return true;
}
c = pointCollector.PointInWorld;
dist = (c - x).Length();
}
else
{
return false;
}
}
if (lastLambda < 1.0f)
{
result.Fraction = lastLambda;
result.Normal = n;
return true;
}
}
return false;
}
#endregion
}
}

View File

@ -0,0 +1,633 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// GJK-EPA collision solver by Nathanael Presson
/// Nov.2006
/// </summary>
public class GjkEpa
{
//private static readonly int _precision = 1 /* U(sizeof(F) == 4)*/;
private static readonly float _infinity = MathHelper.Infinity;
//private static readonly float _pi = (float)Math.PI;
private static readonly float _twoPi = (float)(Math.PI * 2);
private static readonly int _gjkMaxIterations = 128;
private static readonly int _gjkHashSize = 1 << 6;
private static readonly int _gjkHashMask = _gjkHashSize - 1;
private static readonly float _gjkInSimplexEpsilon = 0.0001f;
private static readonly float _gjkSquareInSimplexEpsilon = _gjkInSimplexEpsilon * _gjkInSimplexEpsilon;
private static readonly int _epaMaxIterations = 256;
private static readonly float _epaInFaceEpsilon = 0.01f;
private static readonly float _epaAccuracy = 0.001f;
public static float EpaAccuracy { get { return _epaAccuracy; } }
private static float Abs(float v) { return (v < 0 ? -v : v); }
private static float Sign(float v) { return (v < 0 ? -1 : 1); }
static void Swap<T>(ref T a, ref T b)
{
T t = a;
a = b;
b = t;
}
public class Gjk
{
public class MinkowskiVertice
{
private Vector3 _vertice; /* Minkowski vertice */
private Vector3 _ray; /* Ray */
public Vector3 Vertice { get { return _vertice; } set { _vertice = value; } }
public Vector3 Ray { get { return _ray; } set { _ray = value; } }
}
public class He
{
private Vector3 _ray;
private He _next;
public He Next { get { return _next; } set { _next = value; } }
public Vector3 Ray { get { return _ray; } set { _ray = value; } }
}
private He[] _table = new He[_gjkHashSize];
private Matrix[] _wrotations = new Matrix[2];
private Vector3[] _positions = new Vector3[2];
private ConvexShape[] _shapes = new ConvexShape[2];
private MinkowskiVertice[] _simplex = new MinkowskiVertice[5];
private Vector3 _ray;
private int _order;
private int _iterations;
private float _margin;
private bool _failed;
public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA,
Matrix wrotationB, Vector3 positionB, ConvexShape shapeB)
: this(wrotationA, positionA, shapeA, wrotationB, positionB, shapeB, 0) { }
public Gjk(Matrix wrotationA, Vector3 positionA, ConvexShape shapeA,
Matrix wrotationB, Vector3 positionB, ConvexShape shapeB,
float pmargin)
{
for (int i = 0; i < _simplex.Length; i++)
_simplex[i] = new MinkowskiVertice();
for (int i = 0; i < _wrotations.Length; i++)
_wrotations[i] = new Matrix();
for (int i = 0; i < _positions.Length; i++)
_positions[i] = new Vector3();
_wrotations[0] = wrotationA; _positions[0] = positionA;
_shapes[0] = shapeA;
_wrotations[0].Translation = Vector3.Zero;
_wrotations[1] = wrotationB; _positions[1] = positionB;
_shapes[1] = shapeB;
_wrotations[1].Translation = Vector3.Zero;
//sablock = sa->BeginBlock();
_margin = pmargin;
_failed = false;
}
public bool Failed { get { return _failed; } }
public int Iterations { get { return _iterations; } }
public int Order { get { return _order; } }
public MinkowskiVertice[] Simplex { get { return _simplex; } }
public int Hash(Vector3 v)
{
int h = ((int)(v.X * 15461) ^ (int)(v.Y * 83003) ^ (int)(v.Z * 15473));
return (h * 169639) & _gjkHashMask;
}
public bool FetchSupport()
{
int h = Hash(_ray);
He e = _table[h];
while (e != null)
{
if (e.Ray == _ray)
{
--_order;
return (false);
}
else e = e.Next;
}
e = new He();
e.Ray = _ray;
e.Next = _table[h];
_table[h] = e;
Support(_ray, ref _simplex[++_order]);
return (Vector3.Dot(_ray, _simplex[_order].Vertice) > 0);
}
public Vector3 LocalSupport(Vector3 d, int i)
{
Matrix m = _wrotations[i];
m.Translation = Vector3.Zero;
Vector3 vtx = Vector3.TransformNormal(d, m);
Vector3 result = MathHelper.MatrixToVector(_wrotations[i], _shapes[i].LocalGetSupportingVertex(vtx));
return (result + _positions[i]);
}
public void Support(Vector3 d, ref MinkowskiVertice v)
{
v.Ray = d;
v.Vertice = LocalSupport(d, 0) - LocalSupport(-d, 1) + d * _margin;
}
public bool SolveSimplex2(Vector3 ao, Vector3 ab)
{
if (Vector3.Dot(ab, ao) >= 0)
{
Vector3 cabo = Vector3.Cross(ab, ao);
if (cabo.LengthSquared() > _gjkSquareInSimplexEpsilon)
{ _ray = Vector3.Cross(cabo, ab); }
else
{ return true; }
}
else
{
_order = 0;
_simplex[0].Ray = _simplex[1].Ray;
_simplex[0].Vertice = _simplex[1].Vertice;
_ray = ao;
}
return false;
}
public bool SolveSimplex3(Vector3 ao, Vector3 ab, Vector3 ac)
{
return (SolveSimplex3a(ao, ab, ac, Vector3.Cross(ab, ac)));
}
public bool SolveSimplex3a(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 cabc)
{
if ((Vector3.Dot(Vector3.Cross(cabc, ab), ao)) < -_gjkInSimplexEpsilon)
{
_order = 1;
_simplex[0].Vertice = _simplex[1].Vertice;
_simplex[0].Ray = _simplex[1].Ray;
_simplex[1].Vertice = _simplex[2].Vertice;
_simplex[1].Ray = _simplex[2].Ray;
return (SolveSimplex2(ao, ab));
}
else if (Vector3.Dot(Vector3.Cross(cabc, ac), ao) > +_gjkInSimplexEpsilon)
{
_order = 1;
_simplex[1].Vertice = _simplex[2].Vertice;
_simplex[1].Ray = _simplex[2].Ray;
return (SolveSimplex2(ao, ac));
}
else
{
float d = Vector3.Dot(cabc, ao);
if (Abs(d) > _gjkInSimplexEpsilon)
{
if (d > 0)
{ _ray = cabc; }
else
{ _ray = -cabc; Swap<MinkowskiVertice>(ref _simplex[0], ref _simplex[1]); }
return (false);
}
else return (true);
}
}
public bool SolveSimplex4(Vector3 ao, Vector3 ab, Vector3 ac, Vector3 ad)
{
Vector3 crs;
if (Vector3.Dot((crs = Vector3.Cross(ab, ac)), ao) > _gjkInSimplexEpsilon)
{
_order = 2;
_simplex[0].Vertice = _simplex[1].Vertice;
_simplex[0].Ray = _simplex[1].Ray;
_simplex[1].Vertice = _simplex[2].Vertice;
_simplex[1].Ray = _simplex[2].Ray;
_simplex[2].Vertice = _simplex[3].Vertice;
_simplex[2].Ray = _simplex[3].Ray;
return (SolveSimplex3a(ao, ab, ac, crs));
}
else if (Vector3.Dot((crs = Vector3.Cross(ac, ad)), ao) > _gjkInSimplexEpsilon)
{
_order = 2;
_simplex[2].Vertice = _simplex[3].Vertice;
_simplex[2].Ray = _simplex[3].Ray;
return (SolveSimplex3a(ao, ac, ad, crs));
}
else if (Vector3.Dot((crs = Vector3.Cross(ad, ab)), ao) > _gjkInSimplexEpsilon)
{
_order = 2;
_simplex[1].Vertice = _simplex[0].Vertice;
_simplex[1].Ray = _simplex[0].Ray;
_simplex[0].Vertice = _simplex[2].Vertice;
_simplex[0].Ray = _simplex[2].Ray;
_simplex[2].Vertice = _simplex[3].Vertice;
_simplex[2].Ray = _simplex[3].Ray;
return (SolveSimplex3a(ao, ad, ab, crs));
}
else return (true);
}
public bool SearchOrigin()
{
return SearchOrigin(new Vector3(1, 0, 0));
}
public bool SearchOrigin(Vector3 initray)
{
_iterations = 0;
unchecked
{
_order = (int)(-1);
}
_failed = false;
_ray = Vector3.Normalize(initray);
//ClearMemory(table, sizeof(void*) * GJK_hashsize);
for (int i = 0; i < _table.Length; i++)
_table[i] = null;
FetchSupport();
_ray = -_simplex[0].Vertice;
for (; _iterations < _gjkMaxIterations; ++_iterations)
{
float rl = _ray.Length();
_ray /= rl > 0 ? rl : 1;
if (FetchSupport())
{
bool found = (false);
switch (_order)
{
case 1: found = SolveSimplex2(-_simplex[1].Vertice, _simplex[0].Vertice - _simplex[1].Vertice); break;
case 2: found = SolveSimplex3(-_simplex[2].Vertice, _simplex[1].Vertice - _simplex[2].Vertice, _simplex[0].Vertice - _simplex[2].Vertice); break;
case 3: found = SolveSimplex4(-_simplex[3].Vertice, _simplex[2].Vertice - _simplex[3].Vertice, _simplex[1].Vertice - _simplex[3].Vertice, _simplex[0].Vertice - _simplex[3].Vertice); break;
}
if (found) return (true);
}
else return (false);
}
_failed = true;
return (false);
}
public bool EncloseOrigin()
{
switch (_order)
{
/* Point */
case 0: break;
/* Line */
case 1:
Vector3 ab = _simplex[1].Vertice - _simplex[0].Vertice;
Vector3[] b ={ Vector3.Cross(ab, new Vector3(1, 0, 0)),
Vector3.Cross(ab, new Vector3(0, 1, 0)),
Vector3.Cross(ab, new Vector3(0, 0, 1)) };
float[] m ={ b[0].LengthSquared(), b[1].LengthSquared(), b[2].LengthSquared() };
Matrix r = Matrix.CreateFromQuaternion(new Quaternion(Vector3.Normalize(ab), _twoPi / 3));
Vector3 w = b[m[0] > m[1] ? m[0] > m[2] ? 0 : 2 : m[1] > m[2] ? 1 : 2];
Support(Vector3.Normalize(w), ref _simplex[4]); w = Vector3.TransformNormal(w, r);
Support(Vector3.Normalize(w), ref _simplex[2]); w = Vector3.TransformNormal(w, r);
Support(Vector3.Normalize(w), ref _simplex[3]); w = Vector3.TransformNormal(w, r);
_order = 4;
return true;
/* Triangle */
case 2:
Vector3 n = Vector3.Normalize(Vector3.Cross(_simplex[1].Vertice - _simplex[0].Vertice, _simplex[2].Vertice - _simplex[0].Vertice));
Support(n, ref _simplex[3]);
Support(-n, ref _simplex[4]);
_order = 4;
return true;
/* Tetrahedron */
case 3: return (true);
/* Hexahedron */
case 4: return (true);
}
return (false);
}
}
public class Epa
{
public class Face
{
public Gjk.MinkowskiVertice[] _vertices = new Gjk.MinkowskiVertice[3];
public Face[] _faces = new Face[3];
public int[] _e = new int[3];
public Vector3 _n;
public float _d;
public int _mark;
public Face _prev;
public Face _next;
}
private Gjk _gjk;
private Face _root;
private int _nfaces;
private int _iterations;
private Vector3[,] _features = new Vector3[2, 3];
private Vector3[] _nearest = new Vector3[2];
private Vector3 _normal;
private float _depth;
private bool _failed;
public Epa(Gjk gjk)
{
this._gjk = gjk;
}
public bool Failed { get { return _failed; } }
public int Iterations { get { return _iterations; } }
public Vector3 Normal { get { return _normal; } }
public Vector3[] Nearest { get { return _nearest; } }
public Vector3 GetCoordinates(Face face)
{
Vector3 o = face._n * -face._d;
float[] a ={ Vector3.Cross(face._vertices[0].Vertice - o, face._vertices[1].Vertice - o).Length(),
Vector3.Cross(face._vertices[1].Vertice - o, face._vertices[2].Vertice - o).Length(),
Vector3.Cross(face._vertices[2].Vertice - o, face._vertices[0].Vertice - o).Length()};
float sm = a[0] + a[1] + a[2];
return (new Vector3(a[1], a[2], a[0]) / (sm > 0 ? sm : 1));
}
public Face FindBest()
{
Face bf = null;
if (_root != null)
{
Face cf = _root;
float bd = _infinity;
do
{
if (cf._d < bd) { bd = cf._d; bf = cf; }
} while (null != (cf = cf._next));
}
return bf;
}
public bool Set(ref Face f, Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c)
{
Vector3 nrm = Vector3.Cross(b.Vertice - a.Vertice, c.Vertice - a.Vertice);
float len = nrm.Length();
bool valid = (Vector3.Dot(Vector3.Cross(a.Vertice, b.Vertice), nrm) >= -_epaInFaceEpsilon &&
Vector3.Dot(Vector3.Cross(b.Vertice, c.Vertice), nrm) >= -_epaInFaceEpsilon &&
Vector3.Dot(Vector3.Cross(c.Vertice, a.Vertice), nrm) >= -_epaInFaceEpsilon);
f._vertices[0] = a;
f._vertices[1] = b;
f._vertices[2] = c;
f._mark = 0;
f._n = nrm / (len > 0 ? len : _infinity);
f._d = Max(0, -Vector3.Dot(f._n, a.Vertice));
return valid;
}
public Face NewFace(Gjk.MinkowskiVertice a, Gjk.MinkowskiVertice b, Gjk.MinkowskiVertice c)
{
Face pf = new Face();
if (Set(ref pf, a, b, c))
{
if (_root != null) _root._prev = pf;
pf._prev = null;
pf._next = _root;
_root = pf;
++_nfaces;
}
else
{
pf._prev = pf._next = null;
}
return (pf);
}
public void Detach(ref Face face)
{
if (face._prev != null || face._next != null)
{
--_nfaces;
if (face == _root)
{
_root = face._next;
_root._prev = null;
}
else
{
if (face._next == null)
{
face._prev._next = null;
}
else
{
face._prev._next = face._next;
face._next._prev = face._prev;
}
}
face._prev = face._next = null;
}
}
public void Link(ref Face f0, int e0, ref Face f1, int e1)
{
f0._faces[e0] = f1; f1._e[e1] = e0;
f1._faces[e1] = f0; f0._e[e0] = e1;
}
public Gjk.MinkowskiVertice Support(Vector3 w)
{
Gjk.MinkowskiVertice v = new Gjk.MinkowskiVertice();
_gjk.Support(w, ref v);
return v;
}
private static int[] mod3 ={ 0, 1, 2, 0, 1 };
public int BuildHorizon(int markid, Gjk.MinkowskiVertice w, ref Face f, int e, ref Face cf, ref Face ff)
{
int ne = (0);
if (f._mark != markid)
{
int e1 = (mod3[e + 1]);
if ((Vector3.Dot(f._n, w.Vertice) + f._d) > 0)
{
Face nf = NewFace(f._vertices[e1], f._vertices[e], w);
Link(ref nf, 0, ref f, e);
if (cf != null) Link(ref cf, 1, ref nf, 2); else ff = nf;
cf = nf; ne = 1;
}
else
{
int e2 = (mod3[e + 2]);
Detach(ref f);
f._mark = markid;
ne += BuildHorizon(markid, w, ref f._faces[e1], f._e[e1], ref cf, ref ff);
ne += BuildHorizon(markid, w, ref f._faces[e2], f._e[e2], ref cf, ref ff);
}
}
return (ne);
}
public float EvaluatePD()
{
return EvaluatePD(_epaAccuracy);
}
private int[,] fidx;
private int[,] eidx;
public float EvaluatePD(float accuracy)
{
//Block* sablock = sa->BeginBlock();
Face bestface = null;
int markid = 1;
_depth = -_infinity;
_normal = new Vector3();
_root = null;
_nfaces = 0;
_iterations = 0;
_failed = false;
/* Prepare hull */
if (_gjk.EncloseOrigin())
{
int nfidx = 0;
int neidx = 0;
Gjk.MinkowskiVertice[] basemkv = new Gjk.MinkowskiVertice[5];
Face[] basefaces = new Face[6];
switch (_gjk.Order)
{
/* Tetrahedron */
case 3:
{
fidx = new int[,] { { 2, 1, 0 }, { 3, 0, 1 }, { 3, 1, 2 }, { 3, 2, 0 } };
eidx = new int[,] { { 0, 0, 2, 1 }, { 0, 1, 1, 1 }, { 0, 2, 3, 1 }, { 1, 0, 3, 2 }, { 2, 0, 1, 2 }, { 3, 0, 2, 2 } };
nfidx = 4; neidx = 6;
} break;
/* Hexahedron */
case 4:
{
fidx = new int[,] { { 2, 0, 4 }, { 4, 1, 2 }, { 1, 4, 0 }, { 0, 3, 1 }, { 0, 2, 3 }, { 1, 3, 2 } };
eidx = new int[,] { { 0, 0, 4, 0 }, { 0, 1, 2, 1 }, { 0, 2, 1, 2 }, { 1, 1, 5, 2 }, { 1, 0, 2, 0 }, { 2, 2, 3, 2 }, { 3, 1, 5, 0 }, { 3, 0, 4, 2 }, { 5, 1, 4, 1 } };
nfidx = 6; neidx = 9;
} break;
}
int i;
for (i = 0; i <= _gjk.Order; ++i)
{
//basemkv[i] = (GJK::Mkv*)sa->Allocate(sizeof(GJK::Mkv));
basemkv[i] = new Gjk.MinkowskiVertice();
basemkv[i].Vertice = _gjk.Simplex[i].Vertice;
basemkv[i].Ray = _gjk.Simplex[i].Ray;
}
for (i = 0; i < nfidx; ++i)
{
basefaces[i] = NewFace(basemkv[fidx[i, 0]], basemkv[fidx[i, 1]], basemkv[fidx[i, 2]]);
}
for (i = 0; i < neidx; ++i)
{
Link(ref basefaces[eidx[i, 0]], eidx[i, 1], ref basefaces[eidx[i, 2]], eidx[i, 3]);
}
}
if (0 == _nfaces)
{
return _depth;
}
/* Expand hull */
for (; _iterations < _epaMaxIterations; ++_iterations)
{
Face bf = FindBest();
if (bf != null)
{
Gjk.MinkowskiVertice w = Support(-bf._n);
float d = Vector3.Dot(bf._n, w.Vertice) + bf._d;
bestface = bf;
if (d < -accuracy)
{
Face cf = null;
Face ff = null;
int nf = 0;
Detach(ref bf);
bf._mark = ++markid;
for (int i = 0; i < 3; ++i)
{
nf += BuildHorizon(markid, w, ref bf._faces[i], bf._e[i], ref cf, ref ff);
}
if (nf <= 2) { break; }
Link(ref cf, 1, ref ff, 2);
}
else break;
}
else break;
}
/* Extract contact */
if (bestface != null)
{
Vector3 b = GetCoordinates(bestface);
_normal = bestface._n;
_depth = Max(0, bestface._d);
for (int i = 0; i < 2; ++i)
{
float s = i != 0 ? -1 : 1;
for (int j = 0; j < 3; ++j)
{
_features[i, j] = _gjk.LocalSupport(s * bestface._vertices[j].Ray, i);
}
}
_nearest[0] = _features[0, 0] * b.X + _features[0, 1] * b.Y + _features[0, 2] * b.Z;
_nearest[1] = _features[1, 0] * b.X + _features[1, 1] * b.Y + _features[1, 2] * b.Z;
}
else _failed = true;
return _depth;
}
private float Max(float a, float b)
{
return (a > b ? a : b);
}
private float Min(float a, float b)
{
return (a < b ? a : b);
}
}
}
}

View File

@ -0,0 +1,56 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// EpaPenetrationDepthSolver uses the Expanding Polytope Algorithm to
/// calculate the penetration depth between two convex shapes.
/// </summary>
public class GjkEpaPenetrationDepthSolver : IConvexPenetrationDepthSolver
{
public bool CalculatePenetrationDepth(ISimplexSolver simplexSolver, ConvexShape convexA, ConvexShape convexB, Matrix transformA, Matrix transformB, Vector3 vector, out Vector3 ptrA, out Vector3 ptrB, IDebugDraw debugDraw)
{
float radialmargin = 0;
GjkEpaSolver.Results results;
if (GjkEpaSolver.Collide(convexA, transformA,
convexB, transformB,
radialmargin, out results))
{
// debugDraw->drawLine(results.witnesses[1],results.witnesses[1]+results.normal,btVector3(255,0,0));
//resultOut->addContactPoint(results.normal,results.witnesses[1],-results.depth);
ptrA = results.Witnesses[0];
ptrB = results.Witnesses[1];
return true;
}
ptrA = new Vector3();
ptrB = new Vector3();
return false;
}
}
}

View File

@ -0,0 +1,101 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// GjkEpaSolver contributed under zlib by Nathanael Presson
/// </summary>
public class GjkEpaSolver
{
public struct Results
{
public enum Status
{
Separated, /* Shapes doesnt penetrate */
Penetrating, /* Shapes are penetrating */
GjkFailed, /* GJK phase fail, no big issue, shapes are probably just 'touching' */
EpaFailed, /* EPA phase fail, bigger problem, need to save parameters, and debug */
}
private Vector3[] _witnesses;
private Vector3 _normal;
private float _depth;
private int _epaIterations;
private int _gjkIterations;
private Status _status;
public Vector3[] Witnesses { get { return _witnesses; } set { _witnesses = value; } }
public Vector3 Normal { get { return _normal; } set { _normal = value; } }
public float Depth { get { return _depth; } set { _depth = value; } }
public int EpaIterations { get { return _epaIterations; } set { _epaIterations = value; } }
public int GjkIterations { get { return _gjkIterations; } set { _gjkIterations = value; } }
public Status ResultStatus { get { return _status; } set { _status = value; } }
}
public static bool Collide(ConvexShape shapeA, Matrix wtrsA,
ConvexShape shapeB, Matrix wtrsB,
float radialmargin,
out Results results)
{
/* Initialize */
results = new Results();
results.Witnesses = new Vector3[2];
results.Witnesses[0] =
results.Witnesses[1] =
results.Normal = new Vector3();
results.Depth = 0;
results.ResultStatus = Results.Status.Separated;
results.EpaIterations = 0;
results.GjkIterations = 0;
/* Use GJK to locate origin */
GjkEpa.Gjk gjk = new GjkEpa.Gjk(wtrsA, wtrsA.Translation, shapeA,
wtrsB, wtrsB.Translation, shapeB,
radialmargin + GjkEpa.EpaAccuracy);
bool collide = gjk.SearchOrigin();
results.GjkIterations = gjk.Iterations + 1;
if (collide)
{
/* Then EPA for penetration depth */
GjkEpa.Epa epa = new GjkEpa.Epa(gjk);
float pd = epa.EvaluatePD();
results.EpaIterations = epa.Iterations + 1;
if (pd > 0)
{
results.ResultStatus = Results.Status.Penetrating;
results.Normal = epa.Normal;
results.Depth = pd;
results.Witnesses[0] = epa.Nearest[0];
results.Witnesses[1] = epa.Nearest[1];
return true;
}
else { if (epa.Failed) results.ResultStatus = Results.Status.EpaFailed; }
}
else { if (gjk.Failed) results.ResultStatus = Results.Status.GjkFailed; }
return false;
}
}
}

View File

@ -0,0 +1,343 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
public class GjkPairDetector : DiscreteCollisionDetectorInterface
{
private Vector3 _cachedSeparatingAxis;
private IConvexPenetrationDepthSolver _penetrationDepthSolver;
private ISimplexSolver _simplexSolver;
private ConvexShape _minkowskiA, _minkowskiB;
private bool _ignoreMargin;
private int _lastUsedMethod;
private int _currentIteration;
private int _degenerateSimplex;
private int _catchDegeneracies;
private static int _numDeepPenetrationChecks = 0;
private static int _numGjkChecks = 0;
private const float RelativeError2 = 1.0e-6f;
#region Properties
public int LastUsedMethod
{
get { return _lastUsedMethod; }
set { _lastUsedMethod = value; }
}
public int CurrentIteration
{
get { return _currentIteration; }
set { _currentIteration = value; }
}
public int DegenerateSimplex
{
get { return _degenerateSimplex; }
set { _degenerateSimplex = value; }
}
public int CatchDegeneracies
{
get { return _catchDegeneracies; }
set { _catchDegeneracies = value; }
}
public static int DeepPenetrationChecksCount { get { return _numDeepPenetrationChecks; } }
public static int GjkChecksCount { get { return _numGjkChecks; } }
#endregion
public GjkPairDetector(ConvexShape objectA, ConvexShape objectB,
ISimplexSolver simplexSolver,
IConvexPenetrationDepthSolver penetrationDepthSolver)
{
_cachedSeparatingAxis = new Vector3(0, 0, 1);
_penetrationDepthSolver = penetrationDepthSolver;
_simplexSolver = simplexSolver;
_minkowskiA = objectA;
_minkowskiB = objectB;
_ignoreMargin = false;
_lastUsedMethod = -1;
_catchDegeneracies = 1;
}
public void setMinkowskiA(ConvexShape minkA)
{
_minkowskiA = minkA;
}
public void setMinkowskiB(ConvexShape minkB)
{
_minkowskiB = minkB;
}
public void setCachedSeperatingAxis(Vector3 seperatingAxis)
{
_cachedSeparatingAxis = seperatingAxis;
}
public void setPenetrationDepthSolver(IConvexPenetrationDepthSolver penetrationDepthSolver)
{
this._penetrationDepthSolver = penetrationDepthSolver;
}
public void setIgnoreMargin(bool ignoreMargin)
{
this._ignoreMargin = ignoreMargin;
}
public override void GetClosestPoints(DiscreteCollisionDetectorInterface.ClosestPointInput input, DiscreteCollisionDetectorInterface.Result output, IDebugDraw debugDraw)
{
float distance = 0;
Vector3 normalInB = new Vector3();
Vector3 pointOnA = new Vector3(), pointOnB = new Vector3();
Matrix localTransA = input.TransformA;
Matrix localTransB = input.TransformB;
Vector3 positionOffset = (localTransA.Translation + localTransB.Translation) * 0.5f;
localTransA.Translation -= positionOffset;
localTransB.Translation -= positionOffset;
float marginA = _minkowskiA.Margin;
float marginB = _minkowskiB.Margin;
_numGjkChecks++;
if (_ignoreMargin)
{
marginA = 0;
marginB = 0;
}
_currentIteration = 0;
int gjkMaxIter = 1000;
_cachedSeparatingAxis = new Vector3(0, 1, 0);
bool isValid = false;
bool checkSimplex = false;
bool checkPenetration = true;
_degenerateSimplex = 0;
_lastUsedMethod = -1;
{
float squaredDistance = MathHelper.Infinity;
float delta = 0;
float margin = marginA + marginB;
_simplexSolver.Reset();
while (true)
{
Matrix transABasis = input.TransformA;
transABasis.Translation = Vector3.Zero;
Matrix transBBasis = input.TransformB;
transBBasis.Translation = Vector3.Zero;
Vector3 seperatingAxisInA = Vector3.TransformNormal(-_cachedSeparatingAxis, transABasis);
Vector3 seperatingAxisInB = Vector3.TransformNormal(_cachedSeparatingAxis, transBBasis);
Vector3 pInA = _minkowskiA.LocalGetSupportingVertexWithoutMargin(seperatingAxisInA);
Vector3 qInB = _minkowskiB.LocalGetSupportingVertexWithoutMargin(seperatingAxisInB);
Vector3 pWorld = MathHelper.MatrixToVector(localTransA, pInA);
Vector3 qWorld = MathHelper.MatrixToVector(localTransB, qInB);
Vector3 w = pWorld - qWorld;
delta = Vector3.Dot(_cachedSeparatingAxis, w);
if ((delta > 0.0) && (delta * delta > squaredDistance * input.MaximumDistanceSquared))
{
checkPenetration = false;
break;
}
if (_simplexSolver.InSimplex(w))
{
_degenerateSimplex = 1;
checkSimplex = true;
break;
}
float f0 = squaredDistance - delta;
float f1 = squaredDistance * RelativeError2;
if (f0 <= f1)
{
if (f0 <= 0.0f)
{
_degenerateSimplex = 2;
}
checkSimplex = true;
break;
}
_simplexSolver.AddVertex(w, pWorld, qWorld);
if (!_simplexSolver.Closest(out _cachedSeparatingAxis))
{
_degenerateSimplex = 3;
checkSimplex = true;
break;
}
float previouseSquaredDistance = squaredDistance;
squaredDistance = _cachedSeparatingAxis.LengthSquared();
if (previouseSquaredDistance - squaredDistance <= MathHelper.Epsilon * previouseSquaredDistance)
{
_simplexSolver.BackupClosest(out _cachedSeparatingAxis);
checkSimplex = true;
break;
}
if (_currentIteration++ > gjkMaxIter)
{
#if DEBUG
Console.WriteLine("GjkPairDetector maxIter exceeded: {0}", _currentIteration);
Console.WriteLine("sepAxis=({0},{1},{2}), squaredDistance = {3}, shapeTypeA={4}, shapeTypeB={5}",
_cachedSeparatingAxis.X,
_cachedSeparatingAxis.Y,
_cachedSeparatingAxis.Z,
squaredDistance,
_minkowskiA.ShapeType,
_minkowskiB.ShapeType
);
#endif
break;
}
bool check = (!_simplexSolver.FullSimplex);
if (!check)
{
_simplexSolver.BackupClosest(out _cachedSeparatingAxis);
break;
}
}
if (checkSimplex)
{
_simplexSolver.ComputePoints(out pointOnA, out pointOnB);
normalInB = pointOnA - pointOnB;
float lenSqr = _cachedSeparatingAxis.LengthSquared();
if (lenSqr < 0.0001f)
{
_degenerateSimplex = 5;
}
if (lenSqr > MathHelper.Epsilon * MathHelper.Epsilon)
{
float rlen = 1.0f / (float)Math.Sqrt((float)lenSqr);
normalInB *= rlen;
float s = (float)Math.Sqrt((float)squaredDistance);
BulletDebug.Assert(s > 0);
pointOnA -= _cachedSeparatingAxis * (marginA / s);
pointOnB += _cachedSeparatingAxis * (marginB / s);
distance = ((1 / rlen) - margin);
isValid = true;
_lastUsedMethod = 1;
}
else
{
_lastUsedMethod = 2;
}
}
bool catchDegeneratePenetrationCase =
(_catchDegeneracies != 0 && _penetrationDepthSolver != null && _degenerateSimplex != 0 && ((distance + margin) < 0.01f));
if (checkPenetration && (!isValid || catchDegeneratePenetrationCase))
{
#warning Check this
if (_penetrationDepthSolver != null)
{
Vector3 tmpPointOnA, tmpPointOnB;
_numDeepPenetrationChecks++;
bool isValid2 = _penetrationDepthSolver.CalculatePenetrationDepth(
_simplexSolver, _minkowskiA, _minkowskiB, localTransA, localTransB,
_cachedSeparatingAxis, out tmpPointOnA, out tmpPointOnB,
debugDraw
);
if (isValid2)
{
Vector3 tmpNormalInB = tmpPointOnB - tmpPointOnA;
float lengSqr = tmpNormalInB.LengthSquared();
if (lengSqr > (MathHelper.Epsilon * MathHelper.Epsilon))
{
tmpNormalInB /= (float)Math.Sqrt((float)lengSqr);
float distance2 = -(tmpPointOnA - tmpPointOnB).Length();
if (!isValid || (distance2 < distance))
{
distance = distance2;
pointOnA = tmpPointOnA;
pointOnB = tmpPointOnB;
normalInB = tmpNormalInB;
isValid = true;
_lastUsedMethod = 3;
}
else
{
}
}
else
{
_lastUsedMethod = 4;
}
}
else
{
_lastUsedMethod = 5;
}
}
}
if (isValid)
{
output.AddContactPoint(normalInB, pointOnB + positionOffset, distance);
}
}
}
}
}

View File

@ -0,0 +1,42 @@
/*
Bullet for XNA Copyright (c) 2003-2007 Vsevolod Klementjev http://www.codeplex.com/xnadevru
Bullet original C++ version 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.
*/
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Xna.Framework;
namespace XnaDevRu.BulletX
{
/// <summary>
/// IConvexPenetrationDepthSolver provides an interface for penetration depth calculation.
/// </summary>
public interface IConvexPenetrationDepthSolver
{
bool CalculatePenetrationDepth(
ISimplexSolver simplexSolver,
ConvexShape convexA, ConvexShape convexB,
Matrix transformA, Matrix transformB,
Vector3 vector, out Vector3 ptrA, out Vector3 ptrB,
IDebugDraw debugDraw//, StackAlloc stackAlloc
);
}
}

Some files were not shown because too many files have changed in this diff Show More