1 %module btSoftBody 2 3 %template(btSparseSdf3) btSparseSdf<3>; 4 5 %typemap(javaimports) btSoftBody %{ 6 import com.badlogic.gdx.physics.bullet.BulletBase; 7 import com.badlogic.gdx.physics.bullet.linearmath.*; 8 import com.badlogic.gdx.physics.bullet.collision.*; 9 import com.badlogic.gdx.physics.bullet.dynamics.*; 10 import com.badlogic.gdx.math.Vector3; 11 import com.badlogic.gdx.math.Quaternion; 12 import com.badlogic.gdx.math.Matrix3; 13 import com.badlogic.gdx.math.Matrix4; 14 import com.badlogic.gdx.graphics.Mesh; 15 import com.badlogic.gdx.graphics.g3d.model.MeshPart; 16 %} 17 18 %{ 19 #include <BulletSoftBody/btSoftBody.h> 20 %} 21 22 %ignore btSoftBody::getWorldInfo; 23 %ignore btSoftBody::getRestLengthScale; 24 %ignore btSoftBody::setRestLengthScale; 25 %ignore btSoftBody::getWindVelocity; 26 %ignore btSoftBody::setSoftBodySolver; 27 %ignore btSoftBody::getSoftBodySolver; 28 29 %include "BulletSoftBody/btSoftBody.h" 30 31 %extend btSoftBody { 32 /** 33 * vertexCount: the amount of vertices 34 * vertexSize: the size in bytes of one vertex 35 * posOffset: the offset within a vertex to the position 36 * normalOffset: the offset within a vertex to the normal or negative if none 37 * triangleCount: the amount of triangle (size per triangle = 3 * sizeof(short)) 38 */ btSoftBody(btSoftBodyWorldInfo * worldInfo,float * vertices,int vertexSize,int posOffset,int normalOffset,short * indices,int indexOffset,int numVertices,short * indexMap,int indexMapOffset)39 btSoftBody(btSoftBodyWorldInfo *worldInfo, float *vertices, int vertexSize, int posOffset, int normalOffset, short *indices, int indexOffset, int numVertices, short *indexMap, int indexMapOffset) { 40 int poffset = posOffset / sizeof(btScalar); 41 int noffset = normalOffset / sizeof(btScalar); 42 int size = vertexSize / sizeof(btScalar); 43 btAlignedObjectArray<btVector3> points; 44 45 btSoftBody *result = new btSoftBody(worldInfo); 46 btSoftBody::Material* pm = result->appendMaterial(); 47 pm->m_kLST = 1; 48 pm->m_kAST = 1; 49 pm->m_kVST = 1; 50 pm->m_flags = btSoftBody::fMaterial::Default; 51 52 const btScalar margin = result->getCollisionShape()->getMargin(); 53 int nodeCount = 0; 54 result->m_nodes.resize(numVertices); 55 for (int i = 0; i < numVertices; i++) { 56 const float * const &verts = &vertices[indices[indexOffset+i]*size+poffset]; 57 btVector3 point(verts[0], verts[1], verts[2]); 58 int idx = -1; 59 for (int j = 0; j < nodeCount; j++) { 60 if (result->m_nodes[j].m_x==point) { 61 idx = j; 62 break; 63 } 64 } 65 if (idx < 0) { 66 btSoftBody::Node &node = result->m_nodes[nodeCount]; 67 memset(&node,0,sizeof(btSoftBody::Node)); 68 node.m_x = point; 69 node.m_q = node.m_x; 70 node.m_im = 1; 71 node.m_leaf = result->m_ndbvt.insert(btDbvtVolume::FromCR(node.m_x,margin),&node); 72 node.m_material = pm; 73 if (noffset >= 0) { 74 node.m_n.m_floats[0] = vertices[indices[indexOffset+i]*size+noffset]; 75 node.m_n.m_floats[1] = vertices[indices[indexOffset+i]*size+noffset+1]; 76 node.m_n.m_floats[2] = vertices[indices[indexOffset+i]*size+noffset+2]; 77 } 78 points.push_back(point); 79 idx = nodeCount; 80 nodeCount++; 81 } 82 indexMap[indexMapOffset+i] = (short)idx; 83 } 84 result->m_nodes.resize(nodeCount); 85 86 //const int vertexCount = points.size(); 87 //btSoftBody *result = new btSoftBody(worldInfo, vertexCount, &points[0], 0); 88 89 btAlignedObjectArray<bool> chks; 90 chks.resize(nodeCount * nodeCount, false); 91 for(int i=0; i<numVertices; i+=3) 92 { 93 const int idx[]={indexMap[indexMapOffset+i],indexMap[indexMapOffset+i+1],indexMap[indexMapOffset+i+2]}; 94 #define IDX(_x_,_y_) ((_y_)*nodeCount+(_x_)) 95 for(int j=2,k=0;k<3;j=k++) 96 { 97 if(!chks[IDX(idx[j],idx[k])]) 98 { 99 chks[IDX(idx[j],idx[k])]=true; 100 chks[IDX(idx[k],idx[j])]=true; 101 result->appendLink(idx[j],idx[k]); 102 } 103 } 104 #undef IDX 105 result->appendFace(idx[0],idx[1],idx[2]); 106 } 107 108 result->updateBounds(); 109 return result; 110 } 111 getNodeCount()112 int getNodeCount() { 113 return $self->m_nodes.size(); 114 } 115 getNode(int idx)116 btSoftBody::Node *getNode(int idx) { 117 return &($self->m_nodes[idx]); 118 } 119 120 /* 121 * buffer: must be at least vertexCount*vertexSize big 122 * vertexCount: the amount of vertices to copy (must be equal to or less than getNodeCount()) 123 * vertexSize: the size in bytes of one vertex (must be dividable by sizeof(btScalar)) 124 * posOffset: the offset within a vertex to the position (must be dividable by sizeof(btScalar)) 125 */ getVertices(btScalar * buffer,int vertexCount,int vertexSize,int posOffset)126 void getVertices(btScalar *buffer, int vertexCount, int vertexSize, int posOffset) { 127 int offset = posOffset / (sizeof(btScalar)); 128 int size = vertexSize / (sizeof(btScalar)); 129 for (int i = 0; i < vertexCount; i++) { 130 const int o = i*size+offset; 131 const float *src = $self->m_nodes[i].m_x.m_floats; 132 buffer[o] = src[0]; 133 buffer[o+1] = src[1]; 134 buffer[o+2] = src[2]; 135 } 136 } 137 getVertices(float * vertices,int vertexSize,int posOffset,short * indices,int indexOffset,int numVertices,short * indexMap,int indexMapOffset)138 void getVertices(float *vertices, int vertexSize, int posOffset, short *indices, int indexOffset, int numVertices, short *indexMap, int indexMapOffset) { 139 int poffset = posOffset / (sizeof(btScalar)); 140 int size = vertexSize / (sizeof(btScalar)); 141 for (int i = 0; i < numVertices; i++) { 142 const int vidx = indices[indexOffset+i]*size+poffset; 143 const int pidx = indexMap[indexMapOffset+i]; 144 const float * const &point = $self->m_nodes[pidx].m_x.m_floats; 145 vertices[vidx ] = point[0]; 146 vertices[vidx+1] = point[1]; 147 vertices[vidx+2] = point[2]; 148 } 149 } 150 getVertices(float * vertices,int vertexSize,int posOffset,int normalOffset,short * indices,int indexOffset,int numVertices,short * indexMap,int indexMapOffset)151 void getVertices(float *vertices, int vertexSize, int posOffset, int normalOffset, short *indices, int indexOffset, int numVertices, short *indexMap, int indexMapOffset) { 152 int poffset = posOffset / (sizeof(btScalar)); 153 int noffset = normalOffset / (sizeof(btScalar)); 154 int size = vertexSize / (sizeof(btScalar)); 155 for (int i = 0; i < numVertices; i++) { 156 const int vidx = indices[indexOffset+i]*size+poffset; 157 const int nidx = indices[indexOffset+i]*size+noffset; 158 const int pidx = indexMap[indexMapOffset+i]; 159 const float * const &point = $self->m_nodes[pidx].m_x.m_floats; 160 const float * const &normal = $self->m_nodes[pidx].m_n.m_floats; 161 vertices[vidx ] = point[0]; 162 vertices[vidx+1] = point[1]; 163 vertices[vidx+2] = point[2]; 164 vertices[nidx ] = normal[0]; 165 vertices[nidx+1] = normal[1]; 166 vertices[nidx+2] = normal[2]; 167 } 168 } 169 getFaceCount()170 int getFaceCount() { 171 return $self->m_faces.size(); 172 } 173 getFace(int idx)174 btSoftBody::Face *getFace(int idx) { 175 return &($self->m_faces[idx]); 176 } 177 getIndices(short * buffer,int triangleCount)178 void getIndices(short *buffer, int triangleCount) { 179 const size_t nodeSize = sizeof(btSoftBody::Node); 180 const intptr_t nodeOffset = (intptr_t)(&self->m_nodes[0]); 181 for (int i = 0; i < triangleCount; i++) { 182 const int idx = i * 3; 183 buffer[idx] = ((intptr_t)(self->m_faces[i].m_n[0]) - nodeOffset) / nodeSize; 184 buffer[idx+1] = ((intptr_t)(self->m_faces[i].m_n[1]) - nodeOffset) / nodeSize; 185 buffer[idx+2] = ((intptr_t)(self->m_faces[i].m_n[2]) - nodeOffset) / nodeSize; 186 } 187 } 188 setConfig_kVCF(btScalar v)189 void setConfig_kVCF(btScalar v) { $self->m_cfg.kVCF = v; } setConfig_kDP(btScalar v)190 void setConfig_kDP(btScalar v) { $self->m_cfg.kDP = v; } setConfig_kDG(btScalar v)191 void setConfig_kDG(btScalar v) { $self->m_cfg.kDG = v; } setConfig_kLF(btScalar v)192 void setConfig_kLF(btScalar v) { $self->m_cfg.kLF = v; } setConfig_kPR(btScalar v)193 void setConfig_kPR(btScalar v) { $self->m_cfg.kPR = v; } setConfig_kVC(btScalar v)194 void setConfig_kVC(btScalar v) { $self->m_cfg.kVC = v; } setConfig_kDF(btScalar v)195 void setConfig_kDF(btScalar v) { $self->m_cfg.kDF = v; } setConfig_kMT(btScalar v)196 void setConfig_kMT(btScalar v) { $self->m_cfg.kMT = v; } setConfig_kCHR(btScalar v)197 void setConfig_kCHR(btScalar v) { $self->m_cfg.kCHR = v; } setConfig_kKHR(btScalar v)198 void setConfig_kKHR(btScalar v) { $self->m_cfg.kKHR = v; } setConfig_kSHR(btScalar v)199 void setConfig_kSHR(btScalar v) { $self->m_cfg.kSHR = v; } setConfig_kAHR(btScalar v)200 void setConfig_kAHR(btScalar v) { $self->m_cfg.kAHR = v; } setConfig_kSRHR_CL(btScalar v)201 void setConfig_kSRHR_CL(btScalar v) { $self->m_cfg.kSRHR_CL = v; } setConfig_kSKHR_CL(btScalar v)202 void setConfig_kSKHR_CL(btScalar v) { $self->m_cfg.kSKHR_CL = v; } setConfig_kSSHR_CL(btScalar v)203 void setConfig_kSSHR_CL(btScalar v) { $self->m_cfg.kSSHR_CL = v; } setConfig_kSR_SPLT_CL(btScalar v)204 void setConfig_kSR_SPLT_CL(btScalar v) { $self->m_cfg.kSR_SPLT_CL = v; } setConfig_kSK_SPLT_CL(btScalar v)205 void setConfig_kSK_SPLT_CL(btScalar v) { $self->m_cfg.kSK_SPLT_CL = v; } setConfig_kSS_SPLT_CL(btScalar v)206 void setConfig_kSS_SPLT_CL(btScalar v) { $self->m_cfg.kSS_SPLT_CL = v; } setConfig_maxvolume(btScalar v)207 void setConfig_maxvolume(btScalar v) { $self->m_cfg.maxvolume = v; } setConfig_timescale(btScalar v)208 void setConfig_timescale(btScalar v) { $self->m_cfg.timescale = v; } setConfig_viterations(int v)209 void setConfig_viterations(int v) { $self->m_cfg.viterations = v; } setConfig_piterations(int v)210 void setConfig_piterations(int v) { $self->m_cfg.piterations = v; } setConfig_diterations(int v)211 void setConfig_diterations(int v) { $self->m_cfg.diterations = v; } setConfig_citerations(int v)212 void setConfig_citerations(int v) { $self->m_cfg.citerations = v; } setConfig_collisions(int v)213 void setConfig_collisions(int v) { $self->m_cfg.collisions = v; } 214 };