bool Cloud2CloudDist::Compute(const Cloth& cloth, const wl::PointCloud& pc, double class_threshold, std::vector<int>& groundIndexes, std::vector<int>& offGroundIndexes, unsigned N/*=3*/) { try { //ÕÒµ½Ã¿¸ö¼¤¹âÀ×´ïµãµ½²¼ÁÏÖ±½ÓµÄ¾àÀ룬ÓøþàÀëãÐÖµÀ´¶ÔµãÔƽøÐзÖÀà //Ë«ÏßÐÔ²åÖµ // for each lidar point, find the projection in the cloth grid, and the sub grid which contains it. //use the four corner of the subgrid to do bilinear interpolation; for (int i = 0; i < pc.size(); i++) { double pc_x = pc[i].x; double pc_z = pc[i].z; //½«¸Ã×ø±êÓë²¼ÁϵÄ×óÉϽÇ×ø±êÏà¼õ double deltaX = pc_x - cloth.origin_pos.x; double deltaZ = pc_z - cloth.origin_pos.z; //µÃµ½¼¤¹âµãËùÔÚ²¼ÁÏСÍø¸ñ×óÉϽǵÄ×ø±ê ¼ÙÉèËĸö½Çµã·Ö±ðΪ0 1 2 3 ˳ʱÕë±àºÅ int col0 = int(deltaX / cloth.step_x); int row0 = int(deltaZ / cloth.step_y); int col1 = col0 + 1; int row1 = row0; int col2 = col0 + 1; int row2 = row0 + 1; int col3 = col0; int row3 = row0 + 1; //ÒÔ×ÓÍø¸ñ×óÉϽǽ¨Á¢×ø±êϵ£¬²¢½«Æä¹éÒ»»¯µ½[0,1] double subdeltaX = (deltaX - col0*cloth.step_x) / cloth.step_x; double subdeltaZ = (deltaZ - row0*cloth.step_y) / cloth.step_y; //cout << subdeltaX << " " << subdeltaZ << endl; //Ë«ÏßÐÔ²åÖµ bilinear interpolation; //f(x,y)=f(0,0)(1-x)(1-y)+f(0,1)(1-x)y+f(1,1)xy+f(1,0)x(1-y) double fxy = cloth.getParticle(col0, row0).pos.y * (1 - subdeltaX)*(1 - subdeltaZ) + cloth.getParticle(col3, row3).pos.y * (1 - subdeltaX)*subdeltaZ + cloth.getParticle(col2, row2).pos.y * subdeltaX*subdeltaZ + cloth.getParticle(col1, row1).pos.y * subdeltaX*(1 - subdeltaZ); double height_var = fxy - pc[i].y; if (std::fabs(height_var) < class_threshold) { groundIndexes.push_back(i); } else { offGroundIndexes.push_back(i); } } } catch (const std::bad_alloc&) { //not enough memory return false; } return true; }
bool Cloud2CloudDist::Compute(const Cloth& cloth, const wl::PointCloud& pc, double class_threshold, std::vector<int>& groundIndexes, std::vector<int>& offGroundIndexes, unsigned N/*=3*/) { try { std::list<Point_d> points_2d; std::map<std::string, double >mapstring; // maping coordinates xy->z to query the height value of each point for (int i = 0; i < cloth.getSize(); i++) { const Particle& particle = cloth.getParticleByIndex(i); std::ostringstream ostrx, ostrz; ostrx << particle.pos.x; ostrz << particle.pos.z; mapstring.insert(std::pair<std::string, double>(ostrx.str() + ostrz.str(), particle.pos.y)); points_2d.push_back(Point_d(particle.pos.x, particle.pos.z)); } Tree tree(points_2d.begin(), points_2d.end()); // step two query the nearest point of cloth for each terrain point for (int i = 0; i < pc.size(); i++) { Point_d query(pc[i].x, pc[i].z); Neighbor_search search(tree, query, N); double search_min = 0; for (Neighbor_search::iterator it = search.begin(); it != search.end(); it++) { std::ostringstream ostrx, ostrz; ostrx << it->first.x(); ostrz << it->first.y(); double y = mapstring[ostrx.str() + ostrz.str()]; search_min = search_min + y / N; //if (y > search_min) //{ // search_min = y; //} } if (std::fabs(search_min - pc[i].y) < class_threshold) { groundIndexes.push_back(i); } else { offGroundIndexes.push_back(i); } } } catch (const std::bad_alloc&) { //not enough memory return false; } return true; }
void display(void) { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glClearColor(1, 1, 1, 0); //white background glEnable(GL_LIGHTING); Vector ballLocation(10, -5, 5); float timeStep = .5; float radius = 3; //cloth cloth.clothCalculations(); cloth.gravity(Vector(0, 0, 0.2)*timeStep); cloth.ballCollision(ballLocation, radius); glTranslatef(-5, 5, -10); glRotatef(120, 1, 0, 0); cloth.draw(); //ball glPushMatrix(); glColor3f(0.0f, 0.0f, 1.0f); //blue glTranslatef(ballLocation.v[0], ballLocation.v[1], ballLocation.v[2]); glutSolidSphere(radius-.1, 20, 20); glPopMatrix(); glutSwapBuffers(); glutPostRedisplay(); }
Cloth *ClothCreate(int w,int h,float size) { // simple cloth generation routine that creates a typical square cloth. // better to use a real pipeline to generate these, this is just for testing. int i,j; Cloth *cloth = new Cloth("cloth",w*h); cloth->w=w; cloth->h=h; // later for rendering. for(i=0;i<h;i++) for(j=0;j<w;j++) { cloth->X[i*w+j] = (float3(-0.5f,-0.5f,0)+float3((float)j/(w-1.0f),1.0f-(float)i/(h-1.0f),0)) * size; } for(i=0;i<h;i++) for(j=0;j<w;j++) { if(i<h-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,(i+1)*w+j); // structural if(j<w-1) cloth->CreateSpring(SPRING_STRUCT,i*w+j,i*w+(j+1)); // structural if(j<w-1&&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j+1)); // shear if(j>0 &&i<h-1) cloth->CreateSpring(SPRING_SHEAR ,i*w+j,(i+1)*w+(j-1)); // shear if(i<h-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,(i+2)*w+j); // benders if(j<w-2) cloth->CreateSpring(SPRING_BEND ,i*w+j,i*w+(j+2)); // benders } cloth->UpdateLimits(); return cloth; }
void ClothDemo::Update(float duration) { if (duration <= 0.0f) return; cloth.addForce(Vector3(0.0, -0.02, 0.0)); cloth.addWindForce(Vector3(0.5, 0, 0.2)); cloth.timeStep(duration); cloth.ballCollision(sphere); }
VerletTest1::VerletTest1(Screen *s): VerletLevel(s){ //Player starting position _startPos = Vector3(-1,3,1.5); _player->setPos(_startPos); //MANAGERS CollectibleManager* cm = new CollectibleManager(this,_player); this->addManager(cm); //VERLETS int angle = 270; float size = .3; Cloth* start = new Cloth(Vector2(12,12), size, Vector3(0,0,0), Y, _vManager, angle); start->pinCorners(); Cloth* end = new Cloth(Vector2(12,12), size, Vector3(-26,4,0), Y, _vManager, angle); end->pinCorners(); _vManager->addVerlet(end); _vManager->addVerlet(start); Cloth* c1 = new Cloth(Vector2(12,90), size, Vector3(-3.5,0,0), Y, _vManager, angle); //Offset further two corners, to give cloth some slack Vector3 test1 = c1->getPoint(c1->getCorner(2)); Vector3 test2 = c1->getPoint(c1->getCorner(3)); c1->setPos(c1->getCorner(2),Vector3(-25,test1.y,test1.z)); c1->setPos(c1->getCorner(3),Vector3(-25,test2.y,test2.z)); _vManager->addVerlet(c1); //CONSTRAINTS //Constrain corners to translation on y-axis _cManager->addConstraint(new TranslationConstraint(c1->getCorner(0), Y, 5, c1)); _cManager->addConstraint(new TranslationConstraint(c1->getCorner(1), Y, 5, c1)); _cManager->addConstraint(new TranslationConstraint(c1->getCorner(2), Y, 5, c1)); _cManager->addConstraint(new TranslationConstraint(c1->getCorner(3), Y, 5, c1)); //Create player-controlled constraint _cManager->addConstraint(new TranslationConstraint(6, Y, 7, c1,true)); //COLLECTIBLES float offsetZ = 1.5; cm->addCollectible(new Token(Vector3(-4,-1,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-7,-2,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-10,-1,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-13,0,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-16,1,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-19,2,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-22,1,offsetZ),_player)); //Randomly distributed cm->addCollectible(new Token(Vector3(-2,-1.2,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-4,-0.3,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-11,.3,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-14,0.1,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-16,-.2,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-18,.14,offsetZ),_player)); cm->addCollectible(new Token(Vector3(-21,1,offsetZ),_player)); }
Cloth* createFreeCloth(NxScene* scene, osg::Vec3f origin) { Cloth *regularCloth = new Cloth(scene, origin, 8.0f, 8.0f, 0.2f, 0); if (!regularCloth->getNxCloth()) { printf("Error: Unable to create the cloth for the current scene.\n"); delete regularCloth; } else { //regularCloth->getNxCloth()->attachToShape(*capsule->getShapes(), 0); } return regularCloth; }
Cloth* createAttachedCloth(NxScene* scene, osg::Vec3f origin) { float w = 8.0f; float h = 8.0f; float d = 0.2f; Cloth *regularCloth = new Cloth(scene, origin, w, h, d, 0); if (!regularCloth->getNxCloth()) { printf("Error: Unable to create the cloth for the current scene.\n"); delete regularCloth; } else { int numX = (int)(w/d)+1; int numY = (int)(h/d)+1; int i1 = 0; NxVec3 p1 = regularCloth->getNxCloth()->getPosition(i1); int i2 = numX; NxVec3 p2 = regularCloth->getNxCloth()->getPosition(i2); int i3 = numX*(numY+1); NxVec3 p3 = regularCloth->getNxCloth()->getPosition(i3); int i4 = (numX+1)*(numY+1)-1; NxVec3 p4 = regularCloth->getNxCloth()->getPosition(i4); regularCloth->getNxCloth()->attachVertexToGlobalPosition(i1,p1); regularCloth->getNxCloth()->attachVertexToGlobalPosition(i2,p2); regularCloth->getNxCloth()->attachVertexToGlobalPosition(i3,p3); regularCloth->getNxCloth()->attachVertexToGlobalPosition(i4,p4); } return regularCloth; }
void Draw(const TimeStep &ts) { Vector2 m = ScreenToWorld(Vector2(mouse.posX,mouse.posY), camera, window); // jworld.Step(ts.dt, m); cloth.Step(m, ts.dt); if(!editor.editMode) { camera.position = world->dude->body.GetPosition(); } renderer.ClearScreen(); renderer.SetWorldViewMatrix(camera); // for(size_t i = 0; i < world->entities.size(); i++) { // world->entities[i]->render->Update(ts.dt); // world->entities[i]->render->Draw(&renderer); // } // for(size_t i = 0; i < numParticles; i++) { // renderer.DrawCircle(jworld.particles[i].x, 0.2, Color4f(1.0f, 0.0f, 0.0f, 1.0f)); // } for(size_t i = 0; i < cloth.joint; i++) { renderer.DrawCapsule(cloth.joints[i].p0->x, cloth.joints[i].p1->x, 0.1f, Color4f(1.0f, 0.0f, 0.0f, 1.0f)); } // editor.Draw(renderer); renderer.SwapBuffers(); }
void ClothDemo::Render() { DrawGrid(Vector3(20, 0, 20)); glTranslatef(-2, 8, -2); glRotatef(45, 0, 1, 0); cloth.draw(); const static GLfloat lightPosition[] = { 0, 3, 8, 0 }; glEnable(GL_DEPTH_TEST); glEnable(GL_LIGHTING); glLightfv(GL_LIGHT0, GL_POSITION, lightPosition); glColorMaterial(GL_FRONT_AND_BACK, GL_DIFFUSE); glEnable(GL_LIGHT0); glEnable(GL_COLOR_MATERIAL); glPushMatrix(); glTranslatef(sphere.pos.x, sphere.pos.y, sphere.pos.z); glColor3f(0.9f, 1.0f, 0.0f); glutSolidSphere(sphere.radius - 0.1, 50, 50); glPopMatrix(); glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); glDisable(GL_LIGHT0); }
void cloth::SwFactory::extractCollisionData(const Cloth& cloth, Range<PxVec4> spheres, Range<uint32_t> capsules, Range<PxVec4> planes, Range<uint32_t> convexes, Range<PxVec3> triangles) const { PX_ASSERT(&cloth.getFactory() == this); const SwCloth& swCloth = static_cast<const SwClothImpl&>(cloth).mCloth; PX_ASSERT(spheres.empty() || spheres.size() == swCloth.mStartCollisionSpheres.size()); PX_ASSERT(capsules.empty() || capsules.size() == swCloth.mCapsuleIndices.size() * 2); PX_ASSERT(planes.empty() || planes.size() == swCloth.mStartCollisionPlanes.size()); PX_ASSERT(convexes.empty() || convexes.size() == swCloth.mConvexMasks.size()); PX_ASSERT(triangles.empty() || triangles.size() == swCloth.mStartCollisionTriangles.size()); if(!swCloth.mStartCollisionSpheres.empty() && !spheres.empty()) memcpy(spheres.begin(), &swCloth.mStartCollisionSpheres.front(), swCloth.mStartCollisionSpheres.size() * sizeof(PxVec4)); if(!swCloth.mCapsuleIndices.empty() && !capsules.empty()) memcpy(capsules.begin(), &swCloth.mCapsuleIndices.front(), swCloth.mCapsuleIndices.size() * sizeof(IndexPair)); if(!swCloth.mStartCollisionPlanes.empty() && !planes.empty()) memcpy(planes.begin(), &swCloth.mStartCollisionPlanes.front(), swCloth.mStartCollisionPlanes.size() * sizeof(PxVec4)); if(!swCloth.mConvexMasks.empty() && !convexes.empty()) memcpy(convexes.begin(), &swCloth.mConvexMasks.front(), swCloth.mConvexMasks.size() * sizeof(uint32_t)); if(!swCloth.mStartCollisionTriangles.empty() && !triangles.empty()) memcpy(triangles.begin(), &swCloth.mStartCollisionTriangles.front(), swCloth.mStartCollisionTriangles.size() * sizeof(PxVec3)); }
/* display method called each frame*/ void display(void) { // calculating positions ball_time++; ball_pos.f[2] = cos(ball_time/50.0)*7; cloth1.addForce(Vec3(0,-0.2,0)*TIME_STEPSIZE2); // add gravity each frame, pointing down cloth1.windForce(Vec3(0.5,0,0.2)*TIME_STEPSIZE2); // generate some wind each frame cloth1.timeStep(); // calculate the particle positions of the next frame cloth1.ballCollision(ball_pos,ball_radius); // resolve collision with the ball // drawing glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glDisable(GL_LIGHTING); // drawing some smooth shaded background - because I like it ;) glBegin(GL_POLYGON); glColor3f(0.8f,0.8f,1.0f); glVertex3f(-200.0f,-100.0f,-100.0f); glVertex3f(200.0f,-100.0f,-100.0f); glColor3f(0.4f,0.4f,0.8f); glVertex3f(200.0f,100.0f,-100.0f); glVertex3f(-200.0f,100.0f,-100.0f); glEnd(); glEnable(GL_LIGHTING); glTranslatef(0.0f, 0.25f, z); glRotatef(xRot, 1.0f, 0.0f, 0.0f); glRotatef(yRot, 0.0f, 1.0f, 0.0f); //glTranslatef(-6.5,6,-9.0f); // move camera out and center on the cloth //glRotatef(25,0,1,0); // rotate a bit to see the cloth from the side cloth1.drawShaded(myImage); // finally draw the cloth with smooth shading glPushMatrix(); // to draw the ball we use glutSolidSphere, and need to draw the sphere at the position of the ball glTranslatef(ball_pos.f[0],ball_pos.f[1],ball_pos.f[2]); // hence the translation of the sphere onto the ball position glColor3f(0.4f,0.8f,0.5f); glutSolidSphere(ball_radius-0.1,50,50); // draw the ball, but with a slightly lower radius, otherwise we could get ugly visual artifacts of cloth penetrating the ball slightly glPopMatrix(); glutSwapBuffers(); glutPostRedisplay(); }
void cloth::SwFactory::extractVirtualParticles(const Cloth& cloth, Range<uint32_t[4]> indices, Range<PxVec3> weights) const { PX_ASSERT(this == &cloth.getFactory()); const SwCloth& swCloth = static_cast<const SwClothImpl&>(cloth).mCloth; uint32_t numIndices = cloth.getNumVirtualParticles(); uint32_t numWeights = cloth.getNumVirtualParticleWeights(); PX_ASSERT(indices.size() == numIndices || indices.empty()); PX_ASSERT(weights.size() == numWeights || weights.empty()); if ( weights.size() == numWeights ) { PxVec3* wDestIt = reinterpret_cast<PxVec3*>(weights.begin()); // convert weights from vec4 to vec3 cloth::Vec4fAlignedVector::ConstIterator wIt = swCloth.mVirtualParticleWeights.begin(); cloth::Vec4fAlignedVector::ConstIterator wEnd= wIt + numWeights; for (; wIt != wEnd; ++wIt, ++wDestIt) *wDestIt = PxVec3(wIt->x, wIt->y, wIt->z); PX_ASSERT(wDestIt == weights.end()); } if ( indices.size() == numIndices ) { // convert indices Vec4u* iDestIt = reinterpret_cast<Vec4u*>(indices.begin()); Vector<Vec4us>::Type::ConstIterator iIt = swCloth.mVirtualParticleIndices.begin(); Vector<Vec4us>::Type::ConstIterator iEnd = swCloth.mVirtualParticleIndices.end(); uint32_t numParticles = uint32_t(swCloth.mCurParticles.size()); for (; iIt != iEnd; ++iIt) { // skip dummy indices if (iIt->x < numParticles) // byte offset to element index *iDestIt++ = Vec4u(*iIt); } PX_ASSERT(&array(*iDestIt) == indices.end()); } }
void cloth::SwFactory::extractParticleAccelerations(const Cloth& cloth, Range<PxVec4> destAccelerations) const { PX_ASSERT(&cloth.getFactory() == this); const SwCloth& swCloth = static_cast<const SwClothImpl&>(cloth).mCloth; if(!swCloth.mParticleAccelerations.empty()) { // make sure dest array is big enough PX_ASSERT(destAccelerations.size() == swCloth.mParticleAccelerations.size()); memcpy(destAccelerations.begin(), &swCloth.mParticleAccelerations.front(), swCloth.mParticleAccelerations.size() * sizeof(PxVec4)); } }
void ImplicitClothExample::stepSimulation(float deltaTime) { m_cloth->Simulate(deltaTime); m_cloth->cloth_gravity.y = -9.8;//-9.8;//-9.8;//-9.8;//0;//-9.8;//0;//-9.8;//0;//-9.8; m_cloth->cloth_gravity.z =-9.8;//0;//-9.8;//0;//-9.8; m_cloth->spring_struct=10000000.0f; m_cloth->spring_shear=10000000.0f; //m_cloth->spring_struct=1000000.0f; //m_cloth->spring_shear=1000000.0f; m_cloth->spring_damp = 0;//100; }
void main(int argc, char **argv) { glutInit(&argc, argv); window.width = 1024; window.height = 1024; glutInitWindowSize(window.width, window.height); glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH); window.id = glutCreateWindow("LOL BRO"); world = new World; glutDisplayFunc(MainLoop); //glutIdleFunc(MainLoop); glutMotionFunc(MouseActiveMotion); glutPassiveMotionFunc(MousePassiveMotion); //glfwEnable(GLFW_STICKY_KEYS); //glfwEnable(GLFW_STICKY_MOUSE_BUTTONS); editor.glui = GLUI_Master.create_glui_subwindow(window.id, GLUI_SUBWINDOW_RIGHT ); GLUI_Master.set_glutIdleFunc(MainLoop); GLUI_Master.set_glutKeyboardFunc(Keyboard); GLUI_Master.set_glutSpecialFunc(SpecialKey); GLUI_Master.set_glutMouseFunc(MouseButton); GLUI_Master.set_glutReshapeFunc(Resize); glClearColor(1.0f, 1.0f, 1.0f, 1.0f); int seed = 0x18a8c1db; // LOL BRO srand(seed); editor.CreateControls(); renderer.Init(); Init(); jworld.Init(); cloth.Init(); glMatrixMode(GL_PROJECTION); glLoadIdentity(); glutMainLoop(); }
void cloth::SwFactory::extractSeparationConstraints(const Cloth& cloth, Range<PxVec4> destConstraints) const { PX_ASSERT(&cloth.getFactory() == this); const SwCloth& swCloth = static_cast<const SwClothImpl&>(cloth).mCloth; Vec4fAlignedVector const& srcConstraints = !swCloth.mSeparationConstraints.mTarget.empty() ? swCloth.mSeparationConstraints.mTarget : swCloth.mSeparationConstraints.mStart; if(!srcConstraints.empty()) { // make sure dest array is big enough PX_ASSERT(destConstraints.size() == srcConstraints.size()); memcpy(destConstraints.begin(), &srcConstraints.front(), srcConstraints.size() * sizeof(PxVec4)); } }
/**读取衣片 目前是直接写入 loc当前衣服种类*/ bool Garment::readCloth(char * loc){ //自己写入 allCloth PXWIDTH Cloth *tmp = new Cloth(); if(!tmp->readClothFile(1)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); tmp = new Cloth(); if(!tmp->readClothFile(2)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); tmp = new Cloth(); if(!tmp->readClothFile(3)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); tmp = new Cloth(); if(!tmp->readClothFile(4)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); tmp = new Cloth(); if(!tmp->readClothFile(5)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); tmp = new Cloth(); if(!tmp->readClothFile(6)){ perror("Cloth readClothFile 错误\n"); } allCloth.push_back(*tmp); return true; }
bool Cloud2CloudDist::Compute( const Cloth& cloth, const wl::PointCloud& pc, double class_threshold, std::vector<int>& groundIndexes, std::vector<int>& offGroundIndexes, unsigned N/*=3*/) { CCLib::SimpleCloud particlePoints; if (!particlePoints.reserve(static_cast<unsigned>(cloth.getSize()))) { //not enough memory return false; } for (int i = 0; i < cloth.getSize(); i++) { const Particle& particle = cloth.getParticleByIndex(i); particlePoints.addPoint(CCVector3(static_cast<PointCoordinateType>(particle.pos.x), 0, static_cast<PointCoordinateType>(particle.pos.z))); } CCLib::SimpleCloud pcPoints; if ( !pcPoints.reserve(static_cast<unsigned>(pc.size())) || !pcPoints.enableScalarField()) { //not enough memory return false; } for (size_t i = 0; i < pc.size(); i++) { const wl::Point& P = pc[i]; pcPoints.addPoint(CCVector3(P.x, 0, P.z)); } try { //we spatially 'synchronize' the cloud and particles octrees CCLib::DgmOctree *cloudOctree = 0, *particleOctree = 0; CCLib::DistanceComputationTools::SOReturnCode soCode = CCLib::DistanceComputationTools::synchronizeOctrees ( &particlePoints, &pcPoints, particleOctree, cloudOctree, 0, 0 ); if (soCode != CCLib::DistanceComputationTools::SYNCHRONIZED && soCode != CCLib::DistanceComputationTools::DISJOINT) { //not enough memory (or invalid input) return false; } //additional parameters void* additionalParameters[] = {(void*)(&cloth), (void*)(particleOctree), (void*)(&N) }; int octreeLevel = particleOctree->findBestLevelForAGivenPopulationPerCell(std::max<unsigned>(2, N)); int result = cloudOctree->executeFunctionForAllCellsAtLevel( octreeLevel, ComputeMeanNeighborAltitude, additionalParameters, true, 0, "Rasterization", QThread::idealThreadCount()); delete cloudOctree; cloudOctree = 0; delete particleOctree; particleOctree = 0; if (result == 0) { //something went wrong return false; } //now classify the points for (unsigned i = 0; i < pcPoints.size(); ++i) { if (std::fabs(pcPoints.getPointScalarValue(i) - pc[i].y) < class_threshold) { groundIndexes.push_back(i); } else { offGroundIndexes.push_back(i); } } } catch (const std::bad_alloc&) { //not enough memory return false; } return true; }
void ClothDemo::DebugRender() { cloth.debugDraw(); }