[opengl]弹簧质点法模拟柔性布料以及椭球碰撞的opengl实现

代码大体与http://bbezxcy.iteye.com/blog/2204322相同,修改了部分不稳定的bug,增加了椭球碰撞以及旋转观察的实现

#ifndef GLUT_DISABLE_ATEXIT_HACK #define GLUT_DISABLE_ATEXIT_HACK #endif #define GLEW_STATIC #include #include #include #include #include #include #include //for matrices #include //undefine if u want to use the default bending constraint of pbd #include using namespace std; //using namespace glm; GLfloat rtx = 0.0f, rty = 0.0f, rtz = 0.0; glm::vec3 Up=glm::vec3(0,1,0), Right, viewDir; const int GRID_SIZE=10; //地板砖边长 GLdouble MV[16]; GLint viewport[4]; GLdouble PP[16]; bool isfix[1000]; int dist = -23; //椭球参数 int iStacks = 30; int iSlices = 30; float fRadius = 1; float radius = 1; //object space radius of ellipsoid //float exp1 = 1e-3; const int numX = 20, numY=20; //一行有numx+1个点 const int total_points = (numX+1)*(numY+1); //总点数 //布料顶点位置 速度glm::vec3 Pos[total_points]; glm::vec3 Veloc[total_points]; glm::vec3 force[total_points]; glm::mat4 ellipsoid,invreseEllipsoid; int size = 4; float hsize = size/2.0f; const float frameTime = 1.0f/60.0f; const float mass = 1.0/total_points; const float globalDamp = 0.98; //速度衰减参数 const glm::vec3 gvat = glm::vec3(0,-9.8,0); //重力加速度 const float Spring_K = 2.5; //弹性系数 const float len0 = 4.0/numX; //单边长度 const float tolera = 1.08; //弹性限度 float fuck; //球体运动//视角问题 int oldX=0, oldY=0; const int width = 1024, height = 1024; GLdouble P[16]; int selected_index = -1; int state =1 ; float rX=15, rY=0; void initGL() { //初始化顶点位置 memset(Pos,0,sizeof(Pos)); memset(Veloc,0,sizeof(Veloc)); memset(force,0,sizeof(force)); //fill in positions int count1 = 0; int u = numX + 1; int v = numY + 1; for(int j=0; j<=numY; j++) { for(int i=0; i<=numX; i++) { Pos[count1++] = glm::vec3( ((float(i)/(u-1)) *2-1)* hsize, size+1, ((float(j)/(v-1) )* size)); printf("(%.1lf ,%.1lf)",((float(i)/(u-1)) *2-1)* hsize,((float(j)/(v-1) )* size)); }printf("\n"); //悬挂点为X[0] 和 X[numX] } memset(isfix,0,sizeof(isfix)); isfix[0] = isfix[numX] = 1; fuck = 0; } void DrawEllipsoid(){//画绿色椭球 //设置椭球 ellipsoid = glm::translate(glm::mat4(1),glm::vec3(0,fuck,0)); fuck += 0.01; if(fuck>=4.0)fuck = -1; ellipsoid = glm::rotate(ellipsoid, 45.0f ,glm::vec3(1,0,0)); ellipsoid = glm::scale(ellipsoid, glm::vec3(fRadius,fRadius,fRadius/2)); invreseEllipsoid = glm::inverse(ellipsoid); fuck +=0.005; //画出椭球 glColor3f(0,1,0); glPushMatrix(); glMultMatrixf(glm::value_ptr(ellipsoid)); //半径,经线条数,维线条数 glutWireSphere(fRadius, iSlices, iStacks); glPopMatrix(); } void DrawGrid()//画地板 { glBegin(GL_LINES); glColor3f(0.5f, 0.5f, 0.5f); for(int i=-GRID_SIZE; i<=GRID_SIZE; i++) { glVertex3f((float)i,0,(float)-GRID_SIZE); glVertex3f((float)i,0,(float)GRID_SIZE); glVertex3f((float)-GRID_SIZE,0,(float)i); glVertex3f((float)GRID_SIZE,0,(float)i); } glEnd(); }void drawTextile(){//画布料 //draw polygons int k = 0; glBegin(GL_LINES); glColor3f(1,1,1); for(int i = 0; i <= numX; i ++){ for(int j = 0; j <= numY; j ++){ //cout<1){//上 force[k] += SpringForce(k, k - 2*numX - 2, 2); } if(j1){//左 force[k] += SpringForce(k, k - 2, 2); } k++; } } //剪切弹簧 k = 0; for(i = 0; i <= numY; i ++){ for(j = 0; j <= numX; j ++){ if(i>0&&j>0){//左上 force[k] += SpringForce(k, k - numX - 2, 3); } if(i>0&&j0){//坐下 force[k] += SpringForce(k, k + numX, 3); } k ++; } } }void EllipsoidCollision() { //检测与处理布料和椭球之间的碰撞 for(size_t i=0; iabs(valY)) glutSetCursor(GLUT_CURSOR_LEFT_RIGHT); else glutSetCursor(GLUT_CURSOR_UP_DOWN); Veloc[selected_index] = glm::vec3(0); Pos[selected_index].x += Right[0]*valX ; float newValue = https://www.it610.com/article/Pos[selected_index].y+Up[1]*valY; if(newValue>0) Pos[selected_index].y = newValue; Pos[selected_index].z += Right[2]*valX + Up[2]*valY; } oldX = x; oldY = y; glutPostRedisplay(); } int main(int argc, char * argv[]) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(1024, 1024); glutCreateWindow("Mass-Spring Model"); initGL(); glutDisplayFunc(OnRender); //指定窗口形状变化时的回调函数 glutReshapeFunc(OnReshape); //指定程序空闲时调用函数 glutIdleFunc(StepPhysics); glEnable(GL_DEPTH_TEST); glutMouseFunc(OnMouseDown); glutMotionFunc(OnMouseMove); glutMainLoop(); return 0; }

【[opengl]弹簧质点法模拟柔性布料以及椭球碰撞的opengl实现】

    推荐阅读