/******************************************************************** ** Image Component Library (ICL) ** ** ** ** Copyright (C) 2006-2014 CITEC, University of Bielefeld ** ** Neuroinformatics Group ** ** Website: www.iclcv.org and ** ** http://opensource.cit-ec.de/projects/icl ** ** ** ** File : ICLPhysics/src/ICLPhysics/PhysicsPaper.cpp ** ** Module : ICLPhysics ** ** Author : Christof Elbrechter, Matthias Esau ** ** ** ** ** ** GNU LESSER GENERAL PUBLIC LICENSE ** ** This file may be used under the terms of the GNU Lesser General ** ** Public License version 3.0 as published by the ** ** ** ** Free Software Foundation and appearing in the file LICENSE.LGPL ** ** included in the packaging of this file. Please review the ** ** following information to ensure the license requirements will ** ** be met: http://www.gnu.org/licenses/lgpl-3.0.txt ** ** ** ** The development of this software was supported by the ** ** Excellence Cluster EXC 277 Cognitive Interaction Technology. ** ** The Excellence Cluster EXC 277 is a grant of the Deutsche ** ** Forschungsgemeinschaft (DFG) in the context of the German ** ** Excellence Initiative. ** ** ** ********************************************************************/ #include #include #include #include #include #include #include #include #include #include #include namespace icl{ using namespace utils; using namespace geom; namespace physics{ PhysicsPaper::PhysicsPaper(const PhysicsWorld &world, int nxCells, int nyCells, const Vec *init, bool initWithCorners, const Img8u *texture,const Img8u *backfaceTexture):cells(nxCells,nyCells){ // const int dim = nxCells * nyCells; static const Vec stdcs[4]={ Vec(-1,-1,0,1),Vec(1 ,-1,0,1), Vec(1 , 1,0,1),Vec(-1, 1,0,1) }; const Vec *cs = initWithCorners ? init : stdcs; btVector3 bt[4]; for(int i=0;i<4;++i){ for(int j=0;j<3;++j){ bt[i][j] = icl2bullet(cs[i][j]); } } btSoftBody *s=btSoftBodyHelpers::CreatePatch(*const_cast(world.getWorldInfo()), bt[0],bt[1],bt[3],bt[2],nxCells,nyCells,0,true); setPhysicalObject(s); btSoftBody::tNodeArray & nodes = s->m_nodes; if(!initWithCorners){ for(int i=0;igetCollisionShape()->setMargin(0.18); s->getCollisionShape()->setMargin(icl2bullet(2)); s->appendMaterial(); s->m_materials[0]->m_kLST = 1.0; s->m_materials[0]->m_kAST = 1.0; s->m_materials[0]->m_kVST = 1.0; const Rect r(0,0,nxCells,nyCells); const int d = 4; #define IDX(x,y) x+nxCells*y for(int y=0;y= 3)){ // changed btSoftBody::Material *m = s->appendMaterial(); m->m_kVST = m->m_kAST = m->m_kLST = 0.9; int sizeBefore = s->m_links.size(); s->appendLink(IDX(x,y),IDX(tx,ty), m, true); if(s->m_links.size() == sizeBefore) continue; // link did already exist s->m_links[s->m_links.size()-1].m_bbending=1; constraints.push_back(BendingConstraint(&s->m_links[s->m_links.size()-1], Point(x,y),Point(tx,ty))); } } } } } //std::cout << "created " << s->m_links.size() << " bending constraints" << std::endl; //s->randomizeConstraints(); randomizeLinks(); s->generateClusters(0); s->m_cfg.kLF = 0; s->m_cfg.kDG = 0; s->m_cfg.kMT = 10; s->m_cfg.kDP = 0.1; s->m_cfg.kDF = 1.0; //s->m_cfg.aeromodel = btSoftBody::eAeroModel::V_TwoSided; //s->m_cfg.collisions = btSoftBody::fCollision::CL_SS+btSoftBody::fCollision::CL_RS + btSoftBody::fCollision::CL_SELF; s->m_cfg.collisions = (btSoftBody::fCollision::CL_SS | btSoftBody::fCollision::CL_RS | btSoftBody::fCollision::CL_SELF); //btSoftBody::fCollision::SDF_RS + //btSoftBody::fCollision::CL_SELF); /// creating the scene object for(int i=0;i cpy = backfaceTexture->deepCopy(); #ifdef FLIP_MARKERS_ONLY FiducialDetector fd("bch","[0,4095]","size=1x1"); std::vector fids = fd.detect(cpy.get()); for(size_t i=0;i corners = fids[i].getCorners2D(); Range32s rx(corners[0].x,corners[0].x), ry(corners[0].y,corners[0].y); for(int j=1;j<4;++j){ rx.extend(corners[j].x); ry.extend(corners[j].y); } cpy->setROI(Rect(rx.minVal, ry.minVal, rx.getLength()+1, ry.getLength()+1)); cpy->mirror(axisVert, true); } cpy->setFullROI(); // icl::show( (cvt(backfaceTexture), cvt(cpy.get()) ) ); #else cpy->mirror(axisVert, true); #endif //struct DepthTestOnOffPrimitive : public Primitive{ // bool on; // DepthTestOnOffPrimitive(bool on):Primitive(Primitive::texture),on(on){} // virtual void render(const Primitive::RenderContext &ctx){ // if(on)glEnable(GL_DEPTH_TEST); // else glDisable(GL_DEPTH_TEST); // } // virtual Primitive *copy() const { return new DepthTestOnOffPrimitive(*this); } //}; //addCustomPrimitive(new DepthTestOnOffPrimitive(false)); addTwoSidedTextureGrid(cells.width,cells.height, texture, cpy.get(), &m_vertices[0][0], &m_vertices[0][1], &m_vertices[0][2], &m_normals[0][0], &m_normals[0][1], &m_normals[0][2],4); TwoSidedTextureGridPrimitive * p = (TwoSidedTextureGridPrimitive*)(m_primitives.back()); p->alphaFunc = (int)GL_ALWAYS; //addCustomPrimitive(new DepthTestOnOffPrimitive(true)); }else{ addTextureGrid(cells.width,cells.height, texture, &m_vertices[0][0], &m_vertices[0][1], &m_vertices[0][2], &m_normals[0][0], &m_normals[0][1], &m_normals[0][2], 4); } } setVisible(Primitive::line,false); setColorsFromVertices(Primitive::quad,true); createAllProperties(); s->setTotalMass( 0.01 ); // does not affect anything? for(int i=0;im_links.size();++i){ originalRestLengths.push_back(s->m_links[i].m_rl); } } void PhysicsPaper::resetDeformation(){ btSoftBody *s = getSoftBody(); for(int i=0;im_links.size();++i){ btSoftBody::Link &l = s->m_links[i]; float o = originalRestLengths[i]; l.m_rl = o; l.m_c1 = o*o; } } void PhysicsPaper::moveVertex(const Point &xy, const Vec &pos, float factor){ btSoftBody::tNodeArray & nodes = getSoftBody()->m_nodes; int i = xy.x+cells.width*xy.y; btVector3 t(icl2bullet(pos[0]),icl2bullet(pos[1]),icl2bullet(pos[2])); nodes[i].m_v = (t-nodes[i].m_x)*factor; } void PhysicsPaper::movePosition(const Point32f &paperPos, const Vec &pos, float factor){ const Vec currPos = getInterpolatedPosition(paperPos); const float x = paperPos.x, y = paperPos.y; const int x0 = floor(x), y0 = floor(y); const int x1 = ceil(x), y1 = ceil(y); const Point32f ps[4] = { Point(x0,y0), Point(x1,y0), Point(x0,y1), Point(x1,y1) }; for(int i=0;i<4;++i){ float contribution = iclMax(1.0 - ::sqrt( ::sqr(ps[i].x-x) + ::sqr(ps[i].y-y) ), 0.0); moveVertex( ps[i], pos + (getNodePosition(ps[i])-currPos),factor * contribution); } } Point PhysicsPaper::getNodeIndex(const Vec &v){ btSoftBody::tNodeArray & nodes = getSoftBody()->m_nodes; std::vector ds(nodes.size()); float x=icl2bullet(v[0]),y=icl2bullet(v[1]),z=icl2bullet(v[2]); for(int i=0;im_nodes; const int &nxCells = cells.width; const int &nyCells = cells.height; const int dim = nxCells * nyCells; for(int i=0;im_nodes; const btVector3 &p = nodes[x+cells.width*y].m_x; return Vec(bullet2icl(p[0]),bullet2icl(p[1]),bullet2icl(p[2]),1); } void PhysicsPaper::setNodeMass(const Point &xy, float mass){ getSoftBody()->setMass(xy.x+cells.width*xy.y,mass); } void PhysicsPaper::setNodeMass(const Vec &v, float mass){ setNodeMass(getNodeIndex(v),mass); } void PhysicsPaper::setTotalMass(float mass){ btSoftBody::tNodeArray & nodes = getSoftBody()->m_nodes; for(int i=0;im_nodes; for(int i=0;irandomizeConstraints(); btSoftBody::tLinkArray &links = getSoftBody()->m_links; std::map lookup; for(int i=0;irow && tyrow) ){ c.setStiffness(val); } } } void PhysicsPaper::adaptColStiffness(float val, int col){ for(size_t i=0;icol && txcol) ){ c.setStiffness(val); } } } void PhysicsPaper::adaptGlobalStiffness(float val){ btSoftBody::tLinkArray &links = getSoftBody()->m_links; for(int i=0;iupdateConstants(); unlock(); } static int sign(float x){ return x > 0 ? 1 : -1; } void PhysicsPaper::adaptStiffnessAlongIntersection(const PlaneEquation &plane, float val){ for(size_t i=0;i hits; for(int x=1;xcoords; } static inline Vec lin_interpolate(const Vec &a, const Vec &b, float f){ const float f1 = 1.0-f; return Vec (a[0] * f1 + b[0] * f, a[1] * f1 + b[1] * f, a[2] * f1 + b[2] * f,1); //a * (1-f) + b * f; } Vec PhysicsPaper::getInterpolatedPosition(const Point32f &p){ float x = p.x, y = p.y; int x0 = floor(x), y0 = floor(y); int x1 = ceil(x), y1 = ceil(y); Vec a = getNodePosition(x0,y0); Vec b = getNodePosition(x1,y0); Vec c = getNodePosition(x0,y1); Vec d = getNodePosition(x1,y1); //also wrong orig: float fx = x1 - p.x, fy = y1 - p.y; float fx = 1.0f - (x1 - p.x), fy = 1.0f - (y1 - p.y); return lin_interpolate( lin_interpolate(a,b,fx), lin_interpolate(c,d,fx), fy); } Vec PhysicsPaper::getPosFromPhysics(int x, int y) const{ const btSoftBody::tNodeArray &nodes = getSoftBody()->m_nodes; int idx = x + getDimensions().width * y; return Vec(bullet2icl(nodes[idx].m_x[0]), bullet2icl(nodes[idx].m_x[1]), bullet2icl(nodes[idx].m_x[2]),1); } Vec PhysicsPaper::getNormalFromPhysics(int x, int y){ const btSoftBody::tNodeArray &nodes = getSoftBody()->m_nodes; int idx = x + getDimensions().width * y; return Vec(nodes[idx].m_n[0], nodes[idx].m_n[1], nodes[idx].m_n[2],1); } } }