From 8faac34801a482e98893b4be4f1406c3b7eee095 Mon Sep 17 00:00:00 2001 From: erwincoumans Date: Fri, 6 Sep 2013 18:09:35 -0700 Subject: [PATCH] move ExplititEuler cloth solver to its own file, so it can be replaced by PDB, implicit euler etc add wireframe toggle ('w' key) add --paused command-line option to start simulation in paused mode render cloth using drawPoints method --- .../CpuDemos/deformable/CpuSoftBodyDemo.cpp | 130 ++++++------------ Demos3/CpuDemos/deformable/CpuSoftBodyDemo.h | 4 +- .../deformable/CpuSoftClothDemoInternalData.h | 4 +- Demos3/CpuDemos/deformable/ExplicitEuler.cpp | 106 ++++++++++++++ Demos3/CpuDemos/deformable/ExplicitEuler.h | 15 ++ Demos3/CpuDemos/main_opengl3core.cpp | 13 ++ Demos3/GpuDemos/main_opengl3core.cpp | 4 +- btgui/OpenGLWindow/GLInstancingRenderer.cpp | 4 +- 8 files changed, 183 insertions(+), 97 deletions(-) create mode 100644 Demos3/CpuDemos/deformable/ExplicitEuler.cpp create mode 100644 Demos3/CpuDemos/deformable/ExplicitEuler.h diff --git a/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.cpp b/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.cpp index a45e07f8c..6d5ae1d18 100644 --- a/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.cpp +++ b/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.cpp @@ -14,6 +14,8 @@ #include "stb_image/stb_image.h" #include "CpuSoftClothDemoInternalData.h" +#include "ExplicitEuler.h" + static b3KeyboardCallback oldCallback = 0; extern bool gReset; @@ -107,94 +109,26 @@ struct GraphicsVertex float texcoord[2]; }; -void CpuSoftClothDemo::computeForces() -{ - B3_PROFILE("computeForces"); - b3Vector3 gravityAcceleration = b3MakeVector3(0,-9.8,0); - //f=m*a - for (int i=0;im_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;im_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) - { - m_clothData->m_forces[indexA] += springForce*particleMassA; - } - - if (particleMassB) - { - m_clothData->m_forces[indexB] -= springForce*particleMassB; - } - } - } -} - -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;im_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(); + //wireframe + bool wireframe=true; + if (wireframe) + { + m_instancingRenderer->init(); + m_instancingRenderer->updateCamera(); + m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(1,0,0),b3MakeVector3(1,0,0,1),1); + m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(0,1,0),b3MakeVector3(0,1,0,1),1); + m_instancingRenderer->drawLine(b3MakeVector3(0,0,0),b3MakeVector3(0,0,1),b3MakeVector3(0,0,1,1),1); + + float color[4]={1,0,0,1}; + m_instancingRenderer->drawPoints(m_data->m_clothVertices,color,numPoints,sizeof(GraphicsVertex),2); + } else + { + m_instancingRenderer->renderScene(); + } } void CpuSoftBodyDemo::renderScene() @@ -219,12 +153,15 @@ void CpuSoftClothDemo::clientMoveAndDisplay() float deltaTime = 1./1000.;//1./60.f; //float deltaTime = 1./60.f; - for (int i=0;i<10;i++) - { - computeForces(); - integrateEuler(deltaTime); - } + //write positions + int vertexStride =sizeof(GraphicsVertex);//9 * sizeof(float); + + ExplicitEuler::solveConstraints(m_clothData, (char*)m_data->m_clothVertices, vertexStride, deltaTime); + + + //read positions + m_instancingRenderer->updateShape(m_data->m_clothShapeIndex,m_data->m_clothVertices); } } @@ -290,6 +227,21 @@ void CpuSoftClothDemo::setupScene(const ConstructionInfo& ci) GLint err = glGetError(); b3Assert(err==GL_NO_ERROR); + if (0) + { + //draw a fixed ground box + int strideInBytes = 9*sizeof(float); + int numVertices = sizeof(cube_vertices)/strideInBytes; + int numIndices = sizeof(cube_indices)/sizeof(int); + int shapeId = ci.m_instancingRenderer->registerShape(&cube_vertices[0],numVertices,cube_indices,numIndices); + b3Vector3 position = b3MakeVector3(0,-50,0);//((j+1)&1)+i*2.2,1+j*2.,((j+1)&1)+k*2.2); + b3Quaternion orn(0,0,0,1); + b3Vector4 scaling=b3MakeVector4(100,1,100,1); + float color[4]={0.8,0.8,0.8,1}; + + int id = ci.m_instancingRenderer->registerGraphicsInstance(shapeId,position,orn,color,scaling); + + } GraphicsVertex* cpu_buffer = new GraphicsVertex[width*height]; diff --git a/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.h b/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.h index a6dea2376..0fe89f137 100644 --- a/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.h +++ b/Demos3/CpuDemos/deformable/CpuSoftBodyDemo.h @@ -64,9 +64,7 @@ public: return "CpuSoftCloth"; } - void computeForces(); - void integrateEuler(float deltaTime); - + virtual void clientMoveAndDisplay(); static CpuDemo* MyCreateFunc() diff --git a/Demos3/CpuDemos/deformable/CpuSoftClothDemoInternalData.h b/Demos3/CpuDemos/deformable/CpuSoftClothDemoInternalData.h index 851b92280..3b1400bbd 100644 --- a/Demos3/CpuDemos/deformable/CpuSoftClothDemoInternalData.h +++ b/Demos3/CpuDemos/deformable/CpuSoftClothDemoInternalData.h @@ -2,6 +2,7 @@ #define CPU_SOFTCLOTH_INTERNAL_DATA_H #include "Bullet3Common/b3AlignedObjectArray.h" +#include "Bullet3Common/b3Vector3.h" struct ClothSpring { @@ -20,11 +21,10 @@ struct ClothMaterial struct CpuSoftClothDemoInternalData { b3AlignedObjectArray m_springs; - b3AlignedObjectArray m_materials; + b3AlignedObjectArray m_materials; b3AlignedObjectArray m_velocities; b3AlignedObjectArray m_forces; b3AlignedObjectArray m_particleMasses; - }; #endif //CPU_SOFTCLOTH_INTERNAL_DATA_H diff --git a/Demos3/CpuDemos/deformable/ExplicitEuler.cpp b/Demos3/CpuDemos/deformable/ExplicitEuler.cpp new file mode 100644 index 000000000..9c9605682 --- /dev/null +++ b/Demos3/CpuDemos/deformable/ExplicitEuler.cpp @@ -0,0 +1,106 @@ +#include "ExplicitEuler.h" + +#include "CpuSoftClothDemoInternalData.h" + + + + + +void ExplicitEuler::computeForces(struct CpuSoftClothDemoInternalData* clothData, char* vertexPositions, int vertexStride, float dt) +{ + + B3_PROFILE("computeForces"); + int numPoints = clothData->m_particleMasses.size(); + + b3Vector3 gravityAcceleration = b3MakeVector3(0,-9.8,0); + //f=m*a + for (int i=0;im_particleMasses[i]; + + b3Vector3 particleMassVec = b3MakeVector3(particleMass,particleMass,particleMass,0); + clothData->m_forces[i] = gravityAcceleration*particleMass; + } + } + + + + + + + //add spring forces + for(int i=0;im_springs.size();i++) + { + + int indexA = clothData->m_springs[i].m_particleIndexA; + int indexB = clothData->m_springs[i].m_particleIndexB; + float restLength = clothData->m_springs[i].m_restLength; + const ClothMaterial& mat = clothData->m_materials[clothData->m_springs[i].m_material]; + + const b3Vector3& posA = (const b3Vector3&)vertexPositions[indexA*vertexStride]; + const b3Vector3& posB = (const b3Vector3&)vertexPositions[indexB*vertexStride]; + const b3Vector3& velA = clothData->m_velocities[indexA]; + const b3Vector3& velB = 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 = clothData->m_particleMasses[indexA]; + float particleMassB = clothData->m_particleMasses[indexB]; + + //if (springForce.length()) + { + if (particleMassA) + { + clothData->m_forces[indexA] += springForce*particleMassA; + } + + if (particleMassB) + { + clothData->m_forces[indexB] -= springForce*particleMassB; + } + } + } + +} + +void ExplicitEuler::integrateExplicitEuler(struct CpuSoftClothDemoInternalData* clothData, char* vertexPositions, int vertexStride,float deltaTime) +{ + B3_PROFILE("integrateEuler"); + b3Vector3 deltaTimeVec = b3MakeVector3(deltaTime,deltaTime,deltaTime,0); + + int numPoints = clothData->m_particleMasses.size(); + + for (int i=0;im_particleMasses[i]; + if (mass) + { + + + + b3Vector3 dv = (clothData->m_forces[i]/mass)*deltaTimeVec; + clothData->m_velocities[i]+= dv; + clothData->m_velocities[i]*=0.999; + + b3Vector3& pos = (b3Vector3&)vertexPositions[i*vertexStride]; + + pos += clothData->m_velocities[i]*deltaTimeVec; + } + } + +} + +void ExplicitEuler::solveConstraints(struct CpuSoftClothDemoInternalData* data, char* vertexPositions, int vertexStride,float deltaTime) +{ + computeForces(data,vertexPositions,vertexStride,deltaTime); + + integrateExplicitEuler(data,vertexPositions,vertexStride,deltaTime); +} \ No newline at end of file diff --git a/Demos3/CpuDemos/deformable/ExplicitEuler.h b/Demos3/CpuDemos/deformable/ExplicitEuler.h new file mode 100644 index 000000000..3fc1e6473 --- /dev/null +++ b/Demos3/CpuDemos/deformable/ExplicitEuler.h @@ -0,0 +1,15 @@ + +#ifndef EXPLICIT_EULER_H +#define EXPLICIT_EULER_H + +struct ExplicitEuler +{ + static void computeForces(struct CpuSoftClothDemoInternalData* data, char* vtx, int vertexStride, float dt); + + static void integrateExplicitEuler(struct CpuSoftClothDemoInternalData* data, char* vtx, int vertexStride,float dt); + + static void solveConstraints(struct CpuSoftClothDemoInternalData* data, char* vtx, int vertexStride,float dt); + +}; + +#endif //EXPLICIT_EULER_H \ No newline at end of file diff --git a/Demos3/CpuDemos/main_opengl3core.cpp b/Demos3/CpuDemos/main_opengl3core.cpp index d214ead97..540585b02 100644 --- a/Demos3/CpuDemos/main_opengl3core.cpp +++ b/Demos3/CpuDemos/main_opengl3core.cpp @@ -192,9 +192,22 @@ static void MyMouseButtonCallback(int button, int state, float x, float y) } extern bool useShadowMap; +bool useWireFrame = false; void MyKeyboardCallback(int key, int state) { + + if (key=='w' && state) + { + useWireFrame = !useWireFrame; + if (useWireFrame) + { + glPolygonMode( GL_FRONT_AND_BACK, GL_LINE ); + } else + { + glPolygonMode( GL_FRONT_AND_BACK, GL_FILL ); + } + } if (key=='s' && state) { useShadowMap=!useShadowMap; diff --git a/Demos3/GpuDemos/main_opengl3core.cpp b/Demos3/GpuDemos/main_opengl3core.cpp index 574e40839..b3da7dcd5 100644 --- a/Demos3/GpuDemos/main_opengl3core.cpp +++ b/Demos3/GpuDemos/main_opengl3core.cpp @@ -607,6 +607,8 @@ int main(int argc, char* argv[]) args.GetCmdLineArgument("y_gap", ci.gapY); args.GetCmdLineArgument("z_gap", ci.gapZ); + gPause = args.CheckCmdLineFlag("paused"); + gDebugForceLoadingFromSource = args.CheckCmdLineFlag("load_cl_kernels_from_disk"); gDebugSkipLoadingBinary = args.CheckCmdLineFlag("disable_cached_cl_kernels"); #ifndef B3_NO_PROFILE @@ -726,7 +728,7 @@ int main(int argc, char* argv[]) if (benchmark) { - gPause = false; + char prefixFileName[1024]; char csvFileName[1024]; char detailsFileName[1024]; diff --git a/btgui/OpenGLWindow/GLInstancingRenderer.cpp b/btgui/OpenGLWindow/GLInstancingRenderer.cpp index eb729d370..870abf403 100644 --- a/btgui/OpenGLWindow/GLInstancingRenderer.cpp +++ b/btgui/OpenGLWindow/GLInstancingRenderer.cpp @@ -1318,8 +1318,8 @@ void GLInstancingRenderer::drawPoints(const float* positions, const float color[ glBindBuffer(GL_ARRAY_BUFFER, 0); glBindBuffer(GL_ARRAY_BUFFER, lineVertexBufferObject); glEnableVertexAttribArray(0); - int numFloats = pointStrideInBytes/sizeof(float); - glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, 0, 0); + int numFloats = 3;//pointStrideInBytes/sizeof(float); + glVertexAttribPointer(0, numFloats, GL_FLOAT, GL_FALSE, pointStrideInBytes, 0); glDrawArrays(GL_POINTS, 0, numPoints); glBindVertexArray(0); glPointSize(1);