Conflicts:
	btgui/OpenGLWindow/GLInstancingRenderer.cpp
This commit is contained in:
erwincoumans 2013-09-06 14:34:47 -07:00
commit d0faea90f9
5 changed files with 267 additions and 43 deletions

View File

@ -12,12 +12,18 @@
#include "CpuSoftBodyDemoInternalData.h"
#include "Bullet3Collision/BroadPhaseCollision/b3DynamicBvhBroadphase.h"
#include "stb_image/stb_image.h"
#include "CpuSoftClothDemoInternalData.h"
static b3KeyboardCallback oldCallback = 0;
extern bool gReset;
float clothWidth = 4;
float clothHeight= 4;
int width = 64;
int height = 64;
int numPoints = width*height;
float clothMass = 100.f;
@ -92,6 +98,7 @@ void CpuSoftBodyDemo::exitPhysics()
}
#include "Bullet3Common/shared/b3Float4.h"
struct GraphicsVertex
{
@ -100,44 +107,93 @@ struct GraphicsVertex
float texcoord[2];
};
void CpuSoftClothDemo::renderScene()
void CpuSoftClothDemo::computeForces()
{
if (m_data->m_clothShapeIndex>=0 && m_data->m_clothVertices)
B3_PROFILE("computeForces");
b3Vector3 gravityAcceleration = b3MakeVector3(0,-9.8,0);
//f=m*a
for (int i=0;i<numPoints;i++)
{
GraphicsVertex* cpu_buffer = (GraphicsVertex*)m_data->m_clothVertices;
int width = 256;
int height=256;
static float shift = 0.f;
shift+=0.01;
if (shift>B3_2_PI)
shift-=B3_2_PI;
int numVertices = 0;
// Initial test data for rendering
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
float particleMass = m_clothData->m_particleMasses[i];
b3Vector3 particleMassVec = b3MakeVector3(particleMass,particleMass,particleMass,0);
m_clothData->m_forces[i] = gravityAcceleration*particleMass;
}
}
GraphicsVertex* cpu_buffer = (GraphicsVertex*)m_data->m_clothVertices;
//add spring forces
for(int i=0;i<m_clothData->m_springs.size();i++)
{
int indexA = m_clothData->m_springs[i].m_particleIndexA;
int indexB = m_clothData->m_springs[i].m_particleIndexB;
float restLength = m_clothData->m_springs[i].m_restLength;
const ClothMaterial& mat = m_clothData->m_materials[m_clothData->m_springs[i].m_material];
const b3Vector3& posA = (const b3Vector3&)cpu_buffer[indexA].pos;
const b3Vector3& posB = (const b3Vector3&)cpu_buffer[indexB].pos;
const b3Vector3& velA = m_clothData->m_velocities[indexA];
const b3Vector3& velB = m_clothData->m_velocities[indexB];
b3Vector3 deltaP = posA-posB;
b3Vector3 deltaV = velA-velB;
float dist = deltaP.length();
b3Vector3 deltaPNormalized = deltaP/dist;
float spring = -mat.m_stiffness * (dist-restLength)*100000;
float damper = mat.m_damping * b3Dot(deltaV,deltaPNormalized)*100;
b3Vector3 springForce = (spring+damper)*deltaPNormalized;
float particleMassA = m_clothData->m_particleMasses[indexA];
float particleMassB = m_clothData->m_particleMasses[indexB];
//if (springForce.length())
{
if (particleMassA)
{
double coord = b3Sin(x/5.0+shift)*0.01;
//coord = sin(y/);
m_clothData->m_forces[indexA] += springForce*particleMassA;
}
cpu_buffer[y*width+x].pos[0] = (x/((float)(width-1)))*1;
cpu_buffer[y*width+x].pos[1] = coord;
cpu_buffer[y*width+x].pos[2] = (y/((float)(height-1)))*1;
cpu_buffer[y*width+x].pos[3] = 0.f;
cpu_buffer[y*width+x].normal[0] = 1;
cpu_buffer[y*width+x].normal[1] = 0;
cpu_buffer[y*width+x].normal[2] = 0;
cpu_buffer[y*width+x].texcoord[0] = 1*x/((float)(width-1));
cpu_buffer[y*width+x].texcoord[1] = (1.f-4*y/((float)(height-1)));
numVertices++;
if (particleMassB)
{
m_clothData->m_forces[indexB] -= springForce*particleMassB;
}
}
m_instancingRenderer->updateShape(m_data->m_clothShapeIndex,m_data->m_clothVertices);
}
}
void CpuSoftClothDemo::integrateEuler(float deltaTime)
{
B3_PROFILE("integrateEuler");
b3Vector3 deltaTimeVec = b3MakeVector3(deltaTime,deltaTime,deltaTime,0);
GraphicsVertex* cpu_buffer = (GraphicsVertex*)m_data->m_clothVertices;
for (int i=0;i<numPoints;i++)
{
float mass = m_clothData->m_particleMasses[i];
if (mass)
{
b3Vector3 dv = (m_clothData->m_forces[i]/mass)*deltaTimeVec;
m_clothData->m_velocities[i]+= dv;
m_clothData->m_velocities[i]*=0.999;
b3Vector3& pos = (b3Vector3&) cpu_buffer[i].pos;
pos += m_clothData->m_velocities[i]*deltaTimeVec;
}
}
}
void CpuSoftClothDemo::renderScene()
{
m_instancingRenderer->renderScene();
}
@ -150,14 +206,37 @@ void CpuSoftBodyDemo::clientMoveAndDisplay()
{
GLint err = glGetError();
b3Assert(err==GL_NO_ERROR);
}
void CpuSoftClothDemo::clientMoveAndDisplay()
{
if (m_data->m_clothShapeIndex>=0 && m_data->m_clothVertices)
{
float deltaTime = 1./1000.;//1./60.f;
//float deltaTime = 1./60.f;
for (int i=0;i<10;i++)
{
computeForces();
integrateEuler(deltaTime);
}
m_instancingRenderer->updateShape(m_data->m_clothShapeIndex,m_data->m_clothVertices);
}
}
CpuSoftClothDemo::CpuSoftClothDemo()
{
m_clothData = new CpuSoftClothDemoInternalData();
}
CpuSoftClothDemo::~CpuSoftClothDemo()
{
delete m_clothData;
}
@ -212,8 +291,6 @@ void CpuSoftClothDemo::setupScene(const ConstructionInfo& ci)
b3Assert(err==GL_NO_ERROR);
int width = 256;
int height = 256;
GraphicsVertex* cpu_buffer = new GraphicsVertex[width*height];
memset(cpu_buffer, 0, width*height*sizeof(GraphicsVertex));
@ -225,12 +302,15 @@ void CpuSoftClothDemo::setupScene(const ConstructionInfo& ci)
{
for(int x = 0; x < width; x++)
{
double coord = b3Sin(x/5.0);//*0.01;
double coord = b3Sin(x/5.0)*0.01+1;
//coord = sin(y/);
cpu_buffer[y*width+x].pos[0] = (x/((float)(width-1)))*1;
float posX = (x/((float)(width-1)))*(clothWidth);
float posZ = ((y-height/2.f)/((float)(height-1)))*(clothHeight);
cpu_buffer[y*width+x].pos[0] = posX;
cpu_buffer[y*width+x].pos[1] = coord;
cpu_buffer[y*width+x].pos[2] = (y/((float)(height-1)))*1;
cpu_buffer[y*width+x].pos[2] = posZ;
cpu_buffer[y*width+x].pos[3] = 0.f;
cpu_buffer[y*width+x].normal[0] = 1;
@ -264,7 +344,8 @@ void CpuSoftClothDemo::setupScene(const ConstructionInfo& ci)
indices[baseIndex+3] = x + 1 + y*width;
indices[baseIndex+4] = x+(width+1) + y*width;
indices[baseIndex+5] = x+width + y*width;
numIndices++;
numIndices+=6;
}
}
@ -316,10 +397,112 @@ void CpuSoftClothDemo::setupScene(const ConstructionInfo& ci)
float scaling[4] = {10,10,10,1};
ci.m_instancingRenderer->registerGraphicsInstance(shapeIndex,pos,orn,color,scaling);
ci.m_instancingRenderer->setCameraDistance(4);
ci.m_instancingRenderer->setCameraDistance(24);
ci.m_instancingRenderer->setCameraTargetPosition(pos);
err = glGetError();
b3Assert(err==GL_NO_ERROR);
int numParticles = width*height;
m_clothData->m_forces.resize(numParticles);
m_clothData->m_velocities.resize(numParticles);
m_clothData->m_particleMasses.resize(numParticles);
for(int y = 0; y < height; y++)
{
for(int x = 0; x < width; x++)
{
float mass = clothMass/numParticles;
if (x==0 && y==(height-1))
mass=0.f;
if (x==0 && y==0)
mass=0.f;
int index = x+width*y;
m_clothData->m_particleMasses[index] = mass;
}
}
ClothMaterial mat;
mat.m_stiffness = 0.5;
mat.m_damping = -0.25;
m_clothData->m_materials.push_back(mat);
//add springs
for (int x=0;x<width-1;x++)
{
for (int y=0;y<height;y++)
{
ClothSpring spring;
int indexA = x+y*width;
int indexB = x+1+y*width;
spring.m_particleIndexA = indexA;
spring.m_particleIndexB = indexB;
spring.m_material = 0;
const b3Vector3& posA = (const b3Vector3&) cpu_buffer[indexA].pos;
const b3Vector3& posB = (const b3Vector3&) cpu_buffer[indexB].pos;
spring.m_restLength = (posA-posB).length();
m_clothData->m_springs.push_back(spring);
}
}
for (int x=0;x<width;x++)
{
for (int y=0;y<height-1;y++)
{
ClothSpring spring;
int indexA = x+y*width;
int indexB = x+(y+1)*width;
spring.m_particleIndexA = indexA;
spring.m_particleIndexB = indexB;
spring.m_material = 0;
const b3Vector3& posA = (const b3Vector3&) cpu_buffer[indexA].pos;
const b3Vector3& posB = (const b3Vector3&) cpu_buffer[indexB].pos;
spring.m_restLength = (posA-posB).length();
m_clothData->m_springs.push_back(spring);
}
}
for (int x=0;x<width-1;x++)
{
for (int y=0;y<height-1;y++)
{
{
ClothSpring spring;
int indexA = x+y*width;
int indexB = (x+1)+(y+1)*width;
spring.m_particleIndexA = indexA;
spring.m_particleIndexB = indexB;
spring.m_material = 0;
const b3Vector3& posA = (const b3Vector3&) cpu_buffer[indexA].pos;
const b3Vector3& posB = (const b3Vector3&) cpu_buffer[indexB].pos;
spring.m_restLength = (posA-posB).length();
m_clothData->m_springs.push_back(spring);
}
{
ClothSpring spring;
int indexA = x+1+y*width;
int indexB = (x)+(y+1)*width;
spring.m_particleIndexA = indexA;
spring.m_particleIndexB = indexB;
spring.m_material = 0;
const b3Vector3& posA = (const b3Vector3&) cpu_buffer[indexA].pos;
const b3Vector3& posB = (const b3Vector3&) cpu_buffer[indexB].pos;
spring.m_restLength = (posA-posB).length();
m_clothData->m_springs.push_back(spring);
}
}
}
}

View File

@ -36,6 +36,8 @@ public:
virtual void renderScene();
virtual void clientMoveAndDisplay();
@ -43,8 +45,11 @@ public:
class CpuSoftClothDemo : public CpuSoftBodyDemo
{
protected:
public:
struct CpuSoftClothDemoInternalData* m_clothData;
public:
CpuSoftClothDemo();
virtual ~CpuSoftClothDemo();
@ -59,6 +64,11 @@ class CpuSoftClothDemo : public CpuSoftBodyDemo
return "CpuSoftCloth";
}
void computeForces();
void integrateEuler(float deltaTime);
virtual void clientMoveAndDisplay();
static CpuDemo* MyCreateFunc()
{
CpuDemo* demo = new CpuSoftClothDemo;

View File

@ -1,5 +1,5 @@
#ifndef GPU_SOFTBODY_INTERNAL_DATA_H
#define GPU_SOFTBODY_INTERNAL_DATA_H
#ifndef CPU_SOFTBODY_INTERNAL_DATA_H
#define CPU_SOFTBODY_INTERNAL_DATA_H
//#include "Bullet3OpenCL/Initialize/b3OpenCLUtils.h"
@ -17,5 +17,5 @@ struct CpuSoftBodyDemoInternalData
}
};
#endif//GPU_SOFTBODY_INTERNAL_DATA_H
#endif//CPU_SOFTBODY_INTERNAL_DATA_H

View File

@ -0,0 +1,31 @@
#ifndef CPU_SOFTCLOTH_INTERNAL_DATA_H
#define CPU_SOFTCLOTH_INTERNAL_DATA_H
#include "Bullet3Common/b3AlignedObjectArray.h"
struct ClothSpring
{
int m_particleIndexA;
int m_particleIndexB;
float m_restLength;
int m_material;
};
struct ClothMaterial
{
float m_stiffness;
float m_damping;
};
struct CpuSoftClothDemoInternalData
{
b3AlignedObjectArray<ClothSpring> m_springs;
b3AlignedObjectArray<ClothMaterial> m_materials;
b3AlignedObjectArray<b3Vector3> m_velocities;
b3AlignedObjectArray<b3Vector3> m_forces;
b3AlignedObjectArray<float> m_particleMasses;
};
#endif //CPU_SOFTCLOTH_INTERNAL_DATA_H

View File

@ -107,7 +107,7 @@ b3AlignedObjectArray<const char*> demoNames;
int selectedDemo = 0;
CpuDemo::CreateFunc* allDemos[]=
{
//CpuSoftClothDemo::MyCreateFunc,
CpuSoftClothDemo::MyCreateFunc,
RigidBodyDemo::MyCreateFunc,
RenderDemo::MyCreateFunc,
EmptyDemo::MyCreateFunc,