[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 = 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)