[opengl]弹簧质点模型的opengl实现
实现了一种基于弹簧质点模型的布料仿真程序
论文见:http://wenku.baidu.com/link?url=8rBDraTsWTtTL8cFU0vjhXMyv4RF0npjeizz2CQQI4DvvTrxsN3bNOK91_1jRw7TuVadHuds5VnWzQ8CxP0QSOcY6sEUMKUib44crkbil0K
对于超弹问题,依然没能很好地解决,希望大神给予指导
#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;
GLfloat sim_step = 0.1;
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 exp1 = 1e-3;
const int numX = 20, numY=20;
//一行有numx+1个点
const int total_points = (numX+1)*(numY+1);
//总点数
//布料顶点位置 速度
const int fck = 10000;
glm::vec3 Pos[total_points];
glm::vec3 Veloc[total_points];
glm::vec3 force[total_points];
int size = 4;
float hsize = size/2.0f;
float currentTime,newTime,startTime;
const float mass = 1.0/total_points;
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;
//弹性限度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;
//处理时间
startTime = (float)glutGet(GLUT_ELAPSED_TIME);
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 CalcPos(){//计算新的位置
newTime = (float) glutGet(GLUT_ELAPSED_TIME);
float frameTime = newTime-currentTime;
frameTime/=1000;
currentTime = newTime;
glm::vec3 acc = glm::vec3(0);
//得到的frame就是间隔时间 毫秒
for(size_t i = 0;
i <= total_points;
i ++){
if(isfix[i])continue;
acc = force[i] / mass;
//得到加速度向量
Veloc[i] *= 0.98;
Veloc[i] = Veloc[i] + acc*frameTime;
//得到新的速度值
Pos[i] = Pos[i] + Veloc[i] * frameTime;
}
}void gao(int a,int b,int is){//直线弹簧 要考虑是否是isfix!
glm::vec3 tmp = Pos[b] - Pos[a];
float dis = glm::length(tmp);
float inilen;
if(is == 1)inilen = len0;
if(is == 2) inilen = len0 * 2;
if(is == 3) inilen = len0 * 1.414213;
inilen *= tolera;
if(dis<=inilen)return;
glm::vec3 tmp1 = tmp*(inilen/dis);
if(isfix[a]&&isfix[b]){
return;
}else if(isfix[a]){
Pos[b] = Pos[a] + tmp1;
}else if(isfix[b]){
Pos[a] = Pos[b] - tmp1;
}else{
glm::vec3 mid = (Pos[a] + Pos[b]) * 0.5f;
Pos[a] = mid - tmp1 * 0.5f;
Pos[b] = mid + tmp1 * 0.5f;
}
}//限制每一根弹簧长度
void DynamicConstrain(){
int i,j,k = 0;
for(i = 0;
i <= numY;
i++){
for(j = 0;
j <= numX;
j ++){
if(j!=numX){//右
gao(k,k+1,1);
}
if(i!=numY){//下
gao(k,k + numX + 1,1);
}if(j0){//左下
gao(k, k + numX, 3);
}
k++;
}
}
}
void StepPhysics(){
ComputeForces();
CalcPos();
glutPostRedisplay();
//DynamicConstrain();
Sleep(5);
}void OnReshape(int nw, int nh) {
glViewport(0,0,nw, nh);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(60, (GLfloat)nw / (GLfloat)nh, 1.f, 100.0f);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_PROJECTION_MATRIX, PP);
glMatrixMode(GL_MODELVIEW);
}
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);
glutMainLoop();
return 0;
}
实现效果
![[opengl]弹簧质点模型的opengl实现](https://img.it610.com/image/info8/ea53917e50cf4d809e17bf9ceadb22ab.png)
文章图片
【[opengl]弹簧质点模型的opengl实现】
推荐阅读
- 2.关于OpenGL|2.关于OpenGL 坐标系以及渲染流程
- OpenGL|OpenGL ES之LUT(滤镜基准图)
- OpenGL|OpenGL 绘制甜甜圈深度测试、多边形偏移、裁剪、 混合
- FFmpeg|FFmpeg 开发(07)(FFmpeg + OpenGLES 实现 3D 全景播放器)
- open基础笔记
- Metal|Metal 简述 & API
- 2、OpenGL初探之OpenGL图形API及专有名词
- Android|Android OpenGL 学习笔记
- 1、OpenGL初探之Mac下环境搭建
- 理解|理解 RGB & YUV 颜色编码