void ImplicitSampler::init() { surface_area = 0; pi_over_2 = 0.5*acos(-1); vector<TriIndex> all_tris; BasicTriMesh* mc_mesh = surface->isosurface(64,256,0.01); ll_bound = Vector3(1e10,1e10,1e10); ur_bound = Vector3(-1e10,-1e10,-1e10); for(int t = 0; t < mc_mesh->n_faces(); t++) { BasicTriMesh::FaceVertexIter fv_it = mc_mesh->fv_iter(OpenMesh::FaceHandle(t)); BasicTriMesh::VertexHandle v0 = fv_it.handle(); BasicTriMesh::VertexHandle v1 = (++fv_it).handle(); BasicTriMesh::VertexHandle v2 = (++fv_it).handle(); BasicTriMesh::Point p0 = mc_mesh->point(v0), p1 = mc_mesh->point(v1), p2 = mc_mesh->point(v2); BasicTriMesh::Point raw_normal = (p1-p0) % (p2-p0); double tri_area = 0.5*raw_normal.length(); Vector3 vert0(p0[0],p0[1],p0[2]); Vector3 vert1(p1[0],p1[1],p1[2]); Vector3 vert2(p2[0],p2[1],p2[2]); sampler_tris.push_back(SamplerTri(vert0,vert1,vert2)); ll_bound.expand_min_bound(vert0); ur_bound.expand_max_bound(vert0); ll_bound.expand_min_bound(vert1); ur_bound.expand_max_bound(vert1); ll_bound.expand_min_bound(vert2); ur_bound.expand_max_bound(vert2); if(p0 == p1 || p0 == p2 || p1 == p2 || tri_area < 1e-9) continue; all_tris.push_back(TriIndex(tri_area, t)); surface_area += tri_area; } std::sort(all_tris.begin(),all_tris.end()); global_radius = 2.5*sqrt(surface_area / ((double)num_points)); vector<TriIndex> cum_tris; for(unsigned t = 0; t < all_tris.size(); t++) { TriIndex next_tri = all_tris[t]; if(t == 0) cum_tris.push_back(next_tri); else { TriIndex prev_tri = cum_tris[t-1]; double cum_area = next_tri.area + prev_tri.area; cum_tris.push_back(TriIndex(cum_area, next_tri.tri)); } } time_t cur_time; time(&cur_time); srand(cur_time); for(int i = 0; i < 20; i++) rand(); sampled_pts = new GridPoint[num_points]; double total_area = cum_tris[cum_tris.size()-1].area; for(int s = 0; s < num_points; s++) { double rand_unit = (double)rand() / (double)RAND_MAX; double rand_area = rand_unit*total_area; int rand_ind = this->tri_search(&cum_tris, rand_area, 0, cum_tris.size()-1); TriIndex rand_tri_index = cum_tris[rand_ind]; SamplerTri rand_tri = sampler_tris[rand_tri_index.tri]; double r1 = (double)rand() / (double)RAND_MAX; double r2 = (double)rand() / (double)RAND_MAX; double r1_sqrt = sqrt(r1); Vector3 rand_pt = rand_tri.v1*(1.0-r1_sqrt) + rand_tri.v2*(r1_sqrt*(1.0-r2)) + rand_tri.v3*(r1_sqrt*r2); sampled_pts[s] = GridPoint(rand_pt, s); } grid_res_x = (ur_bound.x-ll_bound.x)/global_radius; grid_res_y = (ur_bound.y-ll_bound.y)/global_radius; grid_res_z = (ur_bound.z-ll_bound.z)/global_radius; grid_res_x = grid_res_x > 300 ? 300 : grid_res_x; grid_res_y = grid_res_y > 300 ? 300 : grid_res_y; grid_res_z = grid_res_z > 300 ? 300 : grid_res_z; cout << "grid res: " << grid_res_x << " : " << grid_res_y << " : " << grid_res_z << endl; delete mc_mesh; }
int b3GpuNarrowPhase::registerConcaveMeshShape(b3AlignedObjectArray<b3Vector3>* vertices, b3AlignedObjectArray<int>* indices,b3Collidable& col, const float* scaling1) { b3Vector3 scaling(scaling1[0],scaling1[1],scaling1[2]); m_data->m_convexData->resize(m_data->m_numAcceleratedShapes+1); m_data->m_convexPolyhedra.resize(m_data->m_numAcceleratedShapes+1); b3ConvexPolyhedronCL& convex = m_data->m_convexPolyhedra.at(m_data->m_convexPolyhedra.size()-1); convex.mC = b3Vector3(0,0,0); convex.mE = b3Vector3(0,0,0); convex.m_extents= b3Vector3(0,0,0); convex.m_localCenter = b3Vector3(0,0,0); convex.m_radius = 0.f; convex.m_numUniqueEdges = 0; int edgeOffset = m_data->m_uniqueEdges.size(); convex.m_uniqueEdgesOffset = edgeOffset; int faceOffset = m_data->m_convexFaces.size(); convex.m_faceOffset = faceOffset; convex.m_numFaces = indices->size()/3; m_data->m_convexFaces.resize(faceOffset+convex.m_numFaces); m_data->m_convexIndices.reserve(convex.m_numFaces*3); for (int i=0;i<convex.m_numFaces;i++) { if (i%256==0) { //printf("i=%d out of %d", i,convex.m_numFaces); } b3Vector3 vert0(vertices->at(indices->at(i*3))*scaling); b3Vector3 vert1(vertices->at(indices->at(i*3+1))*scaling); b3Vector3 vert2(vertices->at(indices->at(i*3+2))*scaling); b3Vector3 normal = ((vert1-vert0).cross(vert2-vert0)).normalize(); b3Scalar c = -(normal.dot(vert0)); m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[0] = normal.getX(); m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[1] = normal.getY(); m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[2] = normal.getZ(); m_data->m_convexFaces[convex.m_faceOffset+i].m_plane[3] = c; int indexOffset = m_data->m_convexIndices.size(); int numIndices = 3; m_data->m_convexFaces[convex.m_faceOffset+i].m_numIndices = numIndices; m_data->m_convexFaces[convex.m_faceOffset+i].m_indexOffset = indexOffset; m_data->m_convexIndices.resize(indexOffset+numIndices); for (int p=0;p<numIndices;p++) { int vi = indices->at(i*3+p); m_data->m_convexIndices[indexOffset+p] = vi;//convexPtr->m_faces[i].m_indices[p]; } } convex.m_numVertices = vertices->size(); int vertexOffset = m_data->m_convexVertices.size(); convex.m_vertexOffset =vertexOffset; m_data->m_convexVertices.resize(vertexOffset+convex.m_numVertices); for (int i=0;i<vertices->size();i++) { m_data->m_convexVertices[vertexOffset+i] = vertices->at(i)*scaling; } (*m_data->m_convexData)[m_data->m_numAcceleratedShapes] = 0; return m_data->m_numAcceleratedShapes++; }
int main(int argc,char** argv) { setCameraDistance(30.f); #define TRISIZE 10.f #ifdef DEBUG_MESH SimdVector3 vert0(-TRISIZE ,0,TRISIZE ); SimdVector3 vert1(TRISIZE ,10,TRISIZE ); SimdVector3 vert2(TRISIZE ,0,-TRISIZE ); meshData.AddTriangle(vert0,vert1,vert2); SimdVector3 vert3(-TRISIZE ,0,TRISIZE ); SimdVector3 vert4(TRISIZE ,0,-TRISIZE ); SimdVector3 vert5(-TRISIZE ,0,-TRISIZE ); meshData.AddTriangle(vert3,vert4,vert5); #else #ifdef ODE_MESH SimdVector3 Size = SimdVector3(15.f,15.f,12.5f); gVertices[0][0] = -Size[0]; gVertices[0][1] = Size[2]; gVertices[0][2] = -Size[1]; gVertices[1][0] = Size[0]; gVertices[1][1] = Size[2]; gVertices[1][2] = -Size[1]; gVertices[2][0] = Size[0]; gVertices[2][1] = Size[2]; gVertices[2][2] = Size[1]; gVertices[3][0] = -Size[0]; gVertices[3][1] = Size[2]; gVertices[3][2] = Size[1]; gVertices[4][0] = 0; gVertices[4][1] = 0; gVertices[4][2] = 0; gIndices[0] = 0; gIndices[1] = 1; gIndices[2] = 4; gIndices[3] = 1; gIndices[4] = 2; gIndices[5] = 4; gIndices[6] = 2; gIndices[7] = 3; gIndices[8] = 4; gIndices[9] = 3; gIndices[10] = 0; gIndices[11] = 4; int vertStride = sizeof(SimdVector3); int indexStride = 3*sizeof(int); TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(NUM_TRIANGLES, gIndices, indexStride, NUM_VERTICES,(float*) &gVertices[0].x(),vertStride); //shapePtr[4] = new TriangleMeshShape(indexVertexArrays); shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays); #else int vertStride = sizeof(SimdVector3); int indexStride = 3*sizeof(int); const int NUM_VERTS_X = 50; const int NUM_VERTS_Y = 50; const int totalVerts = NUM_VERTS_X*NUM_VERTS_Y; const int totalTriangles = 2*(NUM_VERTS_X-1)*(NUM_VERTS_Y-1); SimdVector3* gVertices = new SimdVector3[totalVerts]; int* gIndices = new int[totalTriangles*3]; int i; for ( i=0;i<NUM_VERTS_X;i++) { for (int j=0;j<NUM_VERTS_Y;j++) { gVertices[i+j*NUM_VERTS_X].setValue((i-NUM_VERTS_X*0.5f)*10.f,2.f*sinf((float)i)*cosf((float)j),(j-NUM_VERTS_Y*0.5f)*10.f); } } int index=0; for ( i=0;i<NUM_VERTS_X-1;i++) { for (int j=0;j<NUM_VERTS_Y-1;j++) { gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = j*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = j*NUM_VERTS_X+i; gIndices[index++] = (j+1)*NUM_VERTS_X+i+1; gIndices[index++] = (j+1)*NUM_VERTS_X+i; } } TriangleIndexVertexArray* indexVertexArrays = new TriangleIndexVertexArray(totalTriangles, gIndices, indexStride, totalVerts,(float*) &gVertices[0].x(),vertStride); //shapePtr[4] = new TriangleMeshShape(indexVertexArrays); shapePtr[4] = new BvhTriangleMeshShape(indexVertexArrays); #endif #endif//DEBUG_MESH // GLDebugDrawer debugDrawer; //ConstraintSolver* solver = new SimpleConstraintSolver; ConstraintSolver* solver = new OdeConstraintSolver; CollisionDispatcher* dispatcher = new CollisionDispatcher(); BroadphaseInterface* broadphase = new SimpleBroadphase(); physicsEnvironmentPtr = new CcdPhysicsEnvironment(dispatcher,broadphase); physicsEnvironmentPtr->setGravity(-1,-10,1); PHY_ShapeProps shapeProps; shapeProps.m_do_anisotropic = false; shapeProps.m_do_fh = false; shapeProps.m_do_rot_fh = false; shapeProps.m_friction_scaling[0] = 1.; shapeProps.m_friction_scaling[1] = 1.; shapeProps.m_friction_scaling[2] = 1.; shapeProps.m_inertia = 1.f; shapeProps.m_lin_drag = 0.95999998f; shapeProps.m_ang_drag = 0.89999998f; shapeProps.m_mass = 1.0f; PHY_MaterialProps materialProps; materialProps.m_friction = 0.f;// 50.5f; materialProps.m_restitution = 0.1f; CcdConstructionInfo ccdObjectCi; ccdObjectCi.m_friction = 0.f;//50.5f; ccdObjectCi.m_linearDamping = shapeProps.m_lin_drag; ccdObjectCi.m_angularDamping = shapeProps.m_ang_drag; SimdTransform tr; tr.setIdentity(); for (i=0;i<numObjects;i++) { if (i>0) shapeIndex[i] = 1;//2 = tetrahedron else shapeIndex[i] = 4; } for (i=0;i<numObjects;i++) { shapeProps.m_shape = shapePtr[shapeIndex[i]]; bool isDyna = i>0; if (!i) { //SimdQuaternion orn(0,0,0.1*SIMD_HALF_PI); //ms[i].setWorldOrientation(orn.x(),orn.y(),orn.z(),orn[3]); //ms[i].setWorldPosition(0,-10,0); } else { ms[i].setWorldPosition(10,i*15-10,0); } //either create a few stacks, to show several islands, or create 1 large stack, showing stability //ms[i].setWorldPosition((i*5) % 30,i*15-10,0); ccdObjectCi.m_MotionState = &ms[i]; ccdObjectCi.m_gravity = SimdVector3(0,0,0); ccdObjectCi.m_localInertiaTensor =SimdVector3(0,0,0); if (!isDyna) { shapeProps.m_mass = 0.f; ccdObjectCi.m_mass = shapeProps.m_mass; } else { shapeProps.m_mass = 1.f; ccdObjectCi.m_mass = shapeProps.m_mass; } SimdVector3 localInertia; if (shapeProps.m_mass>0.f) { shapePtr[shapeIndex[i]]->CalculateLocalInertia(shapeProps.m_mass,localInertia); } else { localInertia.setValue(0.f,0.f,0.f); } ccdObjectCi.m_localInertiaTensor = localInertia; ccdObjectCi.m_collisionShape = shapePtr[shapeIndex[i]]; physObjects[i]= new CcdPhysicsController( ccdObjectCi); physicsEnvironmentPtr->addCcdPhysicsController( physObjects[i]); /* if (i==0) { physObjects[i]->SetAngularVelocity(0,0,-2,true); physObjects[i]->GetRigidBody()->setDamping(0,0); } */ //for the line that represents the AABB extents // physicsEnvironmentPtr->setDebugDrawer(&debugDrawer); } return glutmain(argc, argv,640,480,"Static Concave Mesh Demo"); }
void mesh::calculateTangents() { std::vector<float> tans(3*vertCount, 0); std::vector<float> bitans(3*vertCount, 0); tangents.resize(4 * vertCount); //calculate tentative tangents and bitangents for each triangle for (int i = 0; i < triCount; i++) { //find the vertices of the current triangle, and their UV coords int vi1 = triangles[3*i]; int vi2 = triangles[3*i + 1]; int vi3 = triangles[3*i + 2]; glm::vec3 vert0(vertices[3*vi1], vertices[3*vi1 + 1], vertices[3*vi1 + 2]); glm::vec3 vert1(vertices[3*vi2], vertices[3*vi2 + 1], vertices[3*vi2 + 2]); glm::vec3 vert2(vertices[3*vi3], vertices[3*vi3 + 1], vertices[3*vi3 + 2]); glm::vec2 uv0(texCoords[2*vi1], texCoords[2*vi1 + 1]); glm::vec2 uv1(texCoords[2*vi2], texCoords[2*vi2 + 1]); glm::vec2 uv2(texCoords[2*vi3], texCoords[2*vi3 + 1]); //differences in position and UV coords glm::vec3 dPos1 = vert1 - vert0; glm::vec3 dPos2 = vert2 - vert0; glm::vec2 dUV1 = uv1 - uv0; glm::vec2 dUV2 = uv2 - uv0; //calculate and store the tangent and bitangent float coeff = 1.0f / (dUV1.x * dUV2.y - dUV1.y * dUV2.x); glm::vec3 tan = dPos1 * dUV2.y - dPos2 * dUV1.y; glm::vec3 bitan = dPos2 * dUV1.x - dPos1 * dUV2.x; tan *= coeff; bitan *= coeff; tans[3*vi1] += tan.x; tans[3*vi1 + 1] += tan.y; tans[3*vi1 + 2] += tan.z; tans[3*vi2] += tan.x; tans[3*vi2 + 1] += tan.y; tans[3*vi2 + 2] += tan.z; tans[3*vi3] += tan.x; tans[3*vi3 + 1] += tan.y; tans[3*vi3 + 2] += tan.z; bitans[3*vi1] += bitan.x; bitans[3*vi1 + 1] += bitan.y; bitans[3*vi1 + 2] += bitan.z; bitans[3*vi2] += bitan.x; bitans[3*vi2 + 1] += bitan.y; bitans[3*vi2 + 2] += bitan.z; bitans[3*vi3] += bitan.x; bitans[3*vi3 + 1] += bitan.y; bitans[3*vi3 + 2] += bitan.z; } //find the final tangent (and bitangent) for each vertex for (int j = 0; j < vertCount; j++) { glm::vec3 normal (normals[3*j], normals[3*j + 1], normals[3*j + 2]); glm::vec3 tangent (tans[3*j], tans[3*j + 1], tans[3*j + 2]); glm::vec3 bitangent (bitans[3*j], bitans[3*j + 1], bitans[3*j + 2]); glm::normalize(tangent); glm::normalize(bitangent); //orthagonalize glm::vec3 tangent_orth(normal); tangent_orth *= glm::dot(normal, tangent); tangent_orth = tangent - tangent_orth; glm::normalize(tangent_orth); //compute handedness float handedness = 1.0f; glm::vec3 nCrossT = glm::cross(normal, tangent_orth); if(glm::dot(nCrossT, bitangent) > 0) { handedness = 1.0f; } else { handedness = -1.0f; } //store the orthagonalized tangent and handedness tangents[4*j] = tangent_orth.x; tangents[4*j + 1] = tangent_orth.y; tangents[4*j + 2] = tangent_orth.z; tangents[4*j + 3] = handedness; } }