Exemplo n.º 1
0
void VRSprite::updateGeo() {
    //setMesh(makePlaneGeo(width, height, 1, 1));
    GeoPnt3fPropertyRecPtr      pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      norms = GeoVec3fProperty::create();
    GeoVec2fPropertyRefPtr      texs = GeoVec2fProperty::create();
    GeoUInt32PropertyRecPtr     inds = GeoUInt32Property::create();

    float w2 = width*0.5;
    float h2 = height*0.5;
    pos->addValue(Pnt3f(-w2,h2,0));
    pos->addValue(Pnt3f(-w2,-h2,0));
    pos->addValue(Pnt3f(w2,-h2,0));
    pos->addValue(Pnt3f(w2,h2,0));

    texs->addValue(Vec2f(0,1));
    texs->addValue(Vec2f(0,0));
    texs->addValue(Vec2f(1,0));
    texs->addValue(Vec2f(1,1));

    for (int i=0; i<4; i++) {
        norms->addValue(Vec3f(0,0,1));
        inds->addValue(i);
    }

    setType(GL_QUADS);
    setPositions(pos);
    setNormals(norms);
    setTexCoords(texs);
    setIndices(inds);
}
Exemplo n.º 2
0
GeometryTransitPtr CSGGeometry::toOsgGeometry(CGAL::Polyhedron *p) {
	GeoPnt3fPropertyRecPtr positions = GeoPnt3fProperty::create();
	GeoVec3fPropertyRecPtr normals = GeoVec3fProperty::create();
	GeoUInt32PropertyRecPtr indices = GeoUInt32Property::create();

	/*
	 * Iterate over all faces, add their vertices to 'positions' && write indices at
	 * the same time. Results in no shared vertices && therefore no normal interpolation between
	 * faces, but makes cubes look good. Well, well...
	 */

	Matrix localToWorld = getWorldMatrix();
	OSG::Vec3f translation;
	OSG::Quaternion rotation;
	OSG::Vec3f scaleFactor;
	OSG::Quaternion scaleOrientation;
	localToWorld.getTransform(translation, rotation, scaleFactor, scaleOrientation);
	Matrix worldToLocal;
	worldToLocal.invertFrom(localToWorld);

	// Convert indices && positions
	int curIndex = 0;
	for (CGAL::Polyhedron::Facet_const_iterator it = p->facets_begin(); it != p->facets_end(); it++) {
		CGAL::Polyhedron::Halfedge_around_facet_const_circulator circ = it->facet_begin();
		do {
			CGAL::Point cgalPos = circ->vertex()->point();
			// We need to transform each point from global coordinates into our local coordinate system
			// (CGAL uses global, OpenSG has geometry in node-local coords)
			OSG::Vec3f vecPos = OSG::Vec3f(CGAL::to_double(cgalPos.x()),
											  CGAL::to_double(cgalPos.y()),
											  CGAL::to_double(cgalPos.z()));
			OSG::Vec3f localVec = worldToLocal * (vecPos - translation);
			OSG::Pnt3f osgPos(localVec.x(), localVec.y(), localVec.z());

			positions->addValue(osgPos);
			normals->addValue(Vec3f(0,1,0));
			indices->addValue(curIndex);
			curIndex++;
		} while (++circ != it->facet_begin());
	}

	GeoUInt8PropertyRecPtr types = GeoUInt8Property::create();
	types->addValue(GL_TRIANGLES);
	GeoUInt32PropertyRecPtr lengths = GeoUInt32Property::create();
	lengths->addValue(indices->size());

	GeometryRecPtr mesh = Geometry::create();
	mesh->setPositions(positions);
	mesh->setNormals(normals);
	mesh->setIndices(indices);
	mesh->setTypes(types);
	mesh->setLengths(lengths);
	mesh->setMaterial(VRMaterial::getDefault()->getMaterial());
    createSharedIndex(mesh);
	calcVertexNormals(mesh, 0.523598775598 /*30 deg in rad*/);

	return GeometryTransitPtr(mesh);
}
Exemplo n.º 3
0
/** Returns the average of all normals of the mesh (not normalized, can be zero) **/
Vec3f VRGeometry::getAverageNormal() {
    if (!meshSet) return Vec3f(0,1,0);
    GeoVec3fPropertyRecPtr norms = dynamic_cast<GeoVec3fProperty*>(mesh->getNormals());

    Vec3f normal = Vec3f(0,0,0);
    for (uint i=0;i<norms->size();i++) {
        normal += Vec3f(norms->getValue(i));
    }

    normal *= 1./norms->size();

    return normal;
}
Exemplo n.º 4
0
void VRGeometry::readSharedMemory(string segment, string object) {
    VRSharedMemory sm(segment, false);

    int sm_state = sm.getObject<int>(object+"_state");
    while (sm.getObject<int>(object+"_state") == sm_state) {
        cout << "VRGeometry::readSharedMemory: waiting for data: " << sm_state << endl;
        sleep(1);
    }

    // read buffer
    auto sm_types = sm.getVector<int>(object+"_types");
    auto sm_lengths = sm.getVector<int>(object+"_lengths");
    auto sm_pos = sm.getVector<float>(object+"_pos");
    auto sm_norms = sm.getVector<float>(object+"_norms");
    auto sm_inds = sm.getVector<int>(object+"_inds");
    auto sm_cols = sm.getVector<float>(object+"_cols");

    GeoPnt3fPropertyRecPtr pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr norms = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr inds = GeoUInt32Property::create();
    GeoUInt32PropertyRecPtr types = GeoUInt32Property::create();
    GeoUInt32PropertyRecPtr lengths = GeoUInt32Property::create();
    GeoVec4fPropertyRecPtr cols = GeoVec4fProperty::create();

    cout << "SM mesh read: " << sm_types.size() << " " << sm_lengths.size() << " " << sm_pos.size() << " " << sm_norms.size() << " " << sm_inds.size() << " " << sm_cols.size() << endl;

    if (sm_types.size() > 0) for (auto& t : sm_types) types->addValue(t);
    if (sm_lengths.size() > 0) for (auto& l : sm_lengths) lengths->addValue(l);
    for (auto& i : sm_inds) inds->addValue(i);
    if (sm_pos.size() > 0) for (int i=0; i<sm_pos.size()-2; i+=3) pos->addValue(Pnt3f(sm_pos[i], sm_pos[i+1], sm_pos[i+2]));
    if (sm_norms.size() > 0) for (int i=0; i<sm_norms.size()-2; i+=3) norms->addValue(Vec3f(sm_norms[i], sm_norms[i+1], sm_norms[i+2]));
    if (sm_cols.size() > 0) for (int i=0; i<sm_cols.size()-2; i+=3) cols->addValue(Pnt3f(sm_cols[i], sm_cols[i+1], sm_cols[i+2]));

    cout << "osg mesh data: " << types->size() << " " << lengths->size() << " " << pos->size() << " " << norms->size() << " " << inds->size() << " " << cols->size() << endl;

    int N = pos->size();
    if (N == 0) return;

    setTypes(types);
    setLengths(lengths);
    setPositions(pos);
    if (norms->size() == N) setNormals(norms);
    if (cols->size() == N) setColors(cols);
    setIndices(inds);
}
Exemplo n.º 5
0
/** Create a mesh using vectors with positions, normals, indices && optionaly texture coordinates **/
void VRGeometry::create(int type, vector<Vec3f> pos, vector<Vec3f> norms, vector<int> inds, vector<Vec2f> texs) {
    bool doTex = (texs.size() == pos.size());

    GeoUInt8PropertyRecPtr      Type = GeoUInt8Property::create();
    GeoUInt32PropertyRecPtr     Length = GeoUInt32Property::create();
    GeoPnt3fPropertyRecPtr      Pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      Norms = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr     Indices = GeoUInt32Property::create();
    SimpleMaterialRecPtr        Mat = SimpleMaterial::create();
    GeoVec2fPropertyRecPtr      Tex = 0;
    if (doTex) Tex = GeoVec2fProperty::create();


    Type->addValue(type);
    Length->addValue(inds.size());

    //positionen und Normalen
    for(uint i=0;i<pos.size();i++) {
            Pos->addValue(pos[i]);
            Norms->addValue(norms[i]);
            if (doTex) Tex->addValue(texs[i]);
    }

    for(uint i=0;i<inds.size();i++) {
            Indices->addValue(inds[i]);
    }

    Mat->setDiffuse(Color3f(0.8,0.8,0.6));
    Mat->setAmbient(Color3f(0.4, 0.4, 0.2));
    Mat->setSpecular(Color3f(0.1, 0.1, 0.1));

    GeometryRecPtr geo = Geometry::create();
    geo->setTypes(Type);
    geo->setLengths(Length);
    geo->setIndices(Indices);
    geo->setPositions(Pos);
    geo->setNormals(Norms);
    if (doTex) geo->setTexCoords(Tex);
    geo->setMaterial(Mat);

    setMesh(geo);
}
Exemplo n.º 6
0
void VRMolecule::updateCoords() {
    coords_geo->hide();
    if (!doCoords) return;

    coords_geo->show();

    GeoPnt3fPropertyRecPtr      Pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      Norms = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr     Indices = GeoUInt32Property::create();
    GeoVec3fPropertyRecPtr      cols = GeoVec3fProperty::create();

    int i=0;
    for (auto a : atoms) {
        float s = 0.4;
        Vec4d p0 = a.second->getTransformation()[3];
        Pos->addValue( p0 );
        Pos->addValue( p0 + a.second->getTransformation()[0]*s );
        Pos->addValue( p0 + a.second->getTransformation()[1]*s );
        Pos->addValue( p0 + a.second->getTransformation()[2]*s );
        cols->addValue(Vec3d(0,0,0));
        cols->addValue(Vec3d(1,0,0));
        cols->addValue(Vec3d(0,1,0));
        cols->addValue(Vec3d(0,0,1));
        Norms->addValue( Vec3d(0, 1, 0) );
        Norms->addValue( Vec3d(0, 1, 0) );
        Norms->addValue( Vec3d(0, 1, 0) );
        Norms->addValue( Vec3d(0, 1, 0) );
        Indices->addValue(i+0);
        Indices->addValue(i+1);
        Indices->addValue(i+0);
        Indices->addValue(i+2);
        Indices->addValue(i+0);
        Indices->addValue(i+3);
        i+=4;
    }

    // atoms geometry
    VRMaterialPtr mat = VRMaterial::get("coords");
    mat->setLineWidth(2);
    mat->setLit(false);

    coords_geo->setType(GL_LINES);
    coords_geo->setPositions(Pos);
    coords_geo->setNormals(Norms);
    coords_geo->setColors(cols);
    coords_geo->setIndices(Indices);
    coords_geo->setMaterial(mat);
}
Exemplo n.º 7
0
void VRWorkpieceElement::buildGeometry(GeoPnt3fPropertyRecPtr positions,
                                       GeoVec3fPropertyRecPtr normals,
                                       GeoUInt32PropertyRecPtr indices,
                                       uint32_t& index) {
    Vec3d planeDistance = this->size / 2.0f;
    // for each dimension
    for (int sgnIndex = 0; sgnIndex < 2; sgnIndex++) {
        for (int dimension = 0; dimension < 3; dimension++) {
            Vec3d planeNormal = planeOffsetMasks[0][dimension];
            Vec3d planeOffset = mulVec3f(planeOffsetMasks[sgnIndex][dimension], planeDistance);
            Vec3d planeMid = this->offset + planeOffset;
            for (int vertexNum = 0; vertexNum < 4; vertexNum++) {
                Vec3d vertexOffsetMask = vertexOffsetMasks[sgnIndex][dimension][vertexNum];
                Vec3d vertexOffset = mulVec3f(planeDistance, vertexOffsetMask);
                Pnt3d vertexPosition = planeMid + vertexOffset;
                positions->push_back(vertexPosition);
                normals->push_back(planeNormal);
                indices->push_back(index);
                index++;
            }
        }
    }
}
Exemplo n.º 8
0
void VRMesure::processBar(Vec3f p1, Vec3f p2) {
    //p1 -= l->getWorldPosition();
    //p2 -= l->getWorldPosition();
    Vec3f d = p2-p1;

    Vec3f t1, t2;
    if (d[1] < d[0]) t1 = d.cross(Vec3f(0,1,0));//take the biggest axis
    else t1 = d.cross(Vec3f(1,0,0));
    t2 = d.cross(t1);

    t1.normalize();
    t1 *= 0.01;
    t2.normalize();
    t2 *= 0.01;

    GeometryRecPtr geo = l->getMesh();
    GeoPnt3fPropertyRecPtr pos = dynamic_cast<GeoPnt3fProperty*>(geo->getPositions());
    GeoVec3fPropertyRecPtr norms = dynamic_cast<GeoVec3fProperty*>(geo->getNormals());

    pos->setValue(p1+t1, 5);
    pos->setValue(p1+t1, 12);
    pos->setValue(p1+t1, 20);

    pos->setValue(p1+t2, 4);
    pos->setValue(p1+t2, 9);
    pos->setValue(p1+t2, 21);

    pos->setValue(p1-t1, 6);
    pos->setValue(p1-t1, 11);
    pos->setValue(p1-t1, 19);

    pos->setValue(p1-t2, 7);
    pos->setValue(p1-t2, 14);
    pos->setValue(p1-t2, 18);

    pos->setValue(p2+t1, 0);
    pos->setValue(p2+t1, 13);
    pos->setValue(p2+t1, 22);

    pos->setValue(p2+t2, 1);
    pos->setValue(p2+t2, 8);
    pos->setValue(p2+t2, 23);

    pos->setValue(p2-t1, 3);
    pos->setValue(p2-t1, 10);
    pos->setValue(p2-t1, 17);

    pos->setValue(p2-t2, 2);
    pos->setValue(p2-t2, 15);
    pos->setValue(p2-t2, 16);

    norms->setValue(p1+t1, 5);
    norms->setValue(p1+t1, 12);
    norms->setValue(p1+t1, 20);

    norms->setValue(p1+t2, 4);
    norms->setValue(p1+t2, 9);
    norms->setValue(p1+t2, 21);

    norms->setValue(p1-t1, 6);
    norms->setValue(p1-t1, 11);
    norms->setValue(p1-t1, 19);

    norms->setValue(p1-t2, 7);
    norms->setValue(p1-t2, 14);
    norms->setValue(p1-t2, 18);

    norms->setValue(p2+t1, 0);
    norms->setValue(p2+t1, 13);
    norms->setValue(p2+t1, 22);

    norms->setValue(p2+t2, 1);
    norms->setValue(p2+t2, 8);
    norms->setValue(p2+t2, 23);

    norms->setValue(p2-t1, 3);
    norms->setValue(p2-t1, 10);
    norms->setValue(p2-t1, 17);

    norms->setValue(p2-t2, 2);
    norms->setValue(p2-t2, 15);
    norms->setValue(p2-t2, 16);
}
Exemplo n.º 9
0
void VRMolecule::updateGeo() {
    GeoPnt3fPropertyRecPtr      Pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      Norms = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr     Indices = GeoUInt32Property::create();
    GeoVec3fPropertyRecPtr      cols = GeoVec3fProperty::create();

    GeoPnt3fPropertyRecPtr      Pos2 = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      Norms2 = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr     Indices2 = GeoUInt32Property::create();

    float r_scale = 0.6;

    int i=0;
    int j=0;
    for (auto a : atoms) {
        PeriodicTableEntry aP = a.second->getParams();
        cols->addValue(aP.color);
        Pos->addValue(a.second->getTransformation()[3]);
        Norms->addValue( Vec3d(0, r_scale*aP.radius, 0) );
        Indices->addValue(i++);

        // bonds
        for (auto b : a.second->getBonds()) {
            if (b.second.atom2 == 0) { // duplet
                Pos2->addValue(b.second.p1);
                Pos2->addValue(b.second.p2);
                Norms2->addValue( Vec3d(0, 1, 0) );
                Norms2->addValue( Vec3d(0.1*b.second.type, 1,1) );
                Indices2->addValue(j++);
                Indices2->addValue(j++);
                continue;
            }

            if (b.second.atom2->getID() < a.first) {
                PeriodicTableEntry bP = b.second.atom2->getParams();
                Pos2->addValue(a.second->getTransformation()[3]);
                Pos2->addValue(b.second.atom2->getTransformation()[3]);
                Norms2->addValue( Vec3d(0, 1, 0) );
                Norms2->addValue( Vec3d(0.1*b.second.type, r_scale*aP.radius, r_scale*bP.radius) );
                Indices2->addValue(j++);
                Indices2->addValue(j++);
            }
        }
    }

    // atoms geometry
    VRMaterialPtr mat = VRMaterial::get("atoms");
    mat->setPointSize(40);
    mat->setLit(false);
    mat->setVertexShader(a_vp, "moleculesVS");
    mat->setFragmentShader(a_fp, "moleculesFS");
    mat->setGeometryShader(a_gp, "moleculesGS");

    setType(GL_POINTS);
    setPositions(Pos);
    setNormals(Norms);
    setColors(cols);
    setIndices(Indices);
    setMaterial(mat);

    // bonds geometry
    VRMaterialPtr mat2 = VRMaterial::get("molecule_bonds");
    mat2->setLineWidth(5);
    mat2->setLit(false);
    mat2->setVertexShader(b_vp, "moleculeBondsVS");
    mat2->setFragmentShader(b_fp, "moleculeBondsFS");
    mat2->setGeometryShader(b_gp, "moleculeBondsGS");

    bonds_geo->setType(GL_LINES);
    bonds_geo->setPositions(Pos2);
    bonds_geo->setNormals(Norms2);
    bonds_geo->setColors(cols);
    bonds_geo->setIndices(Indices2);
    bonds_geo->setMaterial(mat2);

    updateLabels();
    updateCoords();
}
Exemplo n.º 10
0
void VRStroke::strokeProfile(vector<Vec3f> profile, bool closed, bool lit) {
    mode = 0;
    this->profile = profile;
    this->closed = closed;
    this->lit = lit;

    GeoUInt8PropertyRecPtr      Type = GeoUInt8Property::create();
    GeoUInt32PropertyRecPtr     Length = GeoUInt32Property::create();
    GeoPnt3fPropertyRecPtr      Pos = GeoPnt3fProperty::create();
    GeoVec3fPropertyRecPtr      Norms = GeoVec3fProperty::create();
    GeoVec3fPropertyRecPtr      Colors = GeoVec3fProperty::create();
    GeoUInt32PropertyRecPtr     Indices = GeoUInt32Property::create();

    bool doCaps = closed && profile.size() > 1;

    Vec3f z = Vec3f(0,0,1);
    if (profile.size() == 1) Type->addValue(GL_LINES);
    else Type->addValue(GL_QUADS);

    clearChildren();
    for (uint i=0; i<paths.size(); i++) {
        vector<Vec3f> pnts = paths[i]->getPositions();
        vector<Vec3f> directions = paths[i]->getDirections();
        vector<Vec3f> up_vectors = paths[i]->getUpvectors();
        vector<Vec3f> cols = paths[i]->getColors();

        Vec3f _p;
        for (uint j=0; j<pnts.size(); j++) {
            Vec3f p = pnts[j];
            Vec3f n = directions[j];
            Vec3f u = up_vectors[j];
            Vec3f c = cols[j];

            Matrix m;
            MatrixLookAt(m, Vec3f(0,0,0), n, u);

            // add new profile points && normals
            for (uint k=0; k<profile.size(); k++) {
                Vec3f tmp = profile[k];
                m.mult(tmp, tmp);

                Pos->addValue(p+tmp);
                tmp.normalize();
                Norms->addValue(tmp);
                Colors->addValue(c);
            }

            if (j==0 && profile.size() > 1) continue;

            // add line
            if (profile.size() == 1) {
                int N = Pos->size();
                Indices->addValue(N-2);
                Indices->addValue(N-1);
            } else {
                // add quad
                for (uint k=0; k<profile.size()-1; k++) {
                    int N1 = Pos->size() - 2*profile.size() + k;
                    int N2 = Pos->size() -   profile.size() + k;
                    Indices->addValue(N1);
                    Indices->addValue(N2);
                    Indices->addValue(N2+1);
                    Indices->addValue(N1+1);

                    //cout << "\nN1N2 " << N1 << " " << N2 << " " << N2+1 << " " << N1+1 << flush;
                }

                if (closed) {
                    int N0 = Pos->size() - 2*profile.size();
                    int N1 = Pos->size() - profile.size() - 1;
                    int N2 = Pos->size() - 1;
                    Indices->addValue(N1);
                    Indices->addValue(N2);
                    Indices->addValue(N1+1);
                    Indices->addValue(N0);

                    //cout << "\nN1N2 " << N1 << " " << N2 << " " << N1+1 << " " << N0 << flush;
                }
            }
        }
    }

    Length->addValue(Indices->size());

    // caps
    if (doCaps) {
        int Nt = 0;
        for (uint i=0; i<paths.size(); i++) {
            vector<Vec3f> pnts = paths[i]->getPositions();
            vector<Vec3f> directions = paths[i]->getDirections();
            vector<Vec3f> up_vectors = paths[i]->getUpvectors();
            vector<Vec3f> cols = paths[i]->getColors();

            Matrix m;

             // first cap
            Vec3f p = pnts[0];
            Vec3f n = directions[0];
            Vec3f u = up_vectors[0];
            Vec3f c = cols[0];

            int Ni = Pos->size();
            Pos->addValue(p);
            Norms->addValue(-n);
            Colors->addValue(c);

            MatrixLookAt(m, Vec3f(0,0,0), n, u);

            for (uint k=0; k<profile.size(); k++) {
                Vec3f tmp = profile[k];
                m.mult(tmp, tmp);

                Pos->addValue(p+tmp);
                Norms->addValue(-n);
                Colors->addValue(c);
            }

            for (uint k=1; k<=profile.size(); k++) {
                int j = k+1;
                if (k == profile.size()) j = 1;
                Indices->addValue(Ni);
                Indices->addValue(Ni+k);
                Indices->addValue(Ni+j);
                Nt+=3;
            }

             // last cap
            int N = pnts.size()-1;
            Ni = Pos->size();
            p = pnts[N];
            n = directions[N];
            u = up_vectors[N];
            c = cols[N];

            Pos->addValue(p);
            Norms->addValue(n);
            Colors->addValue(c);

            MatrixLookAt(m, Vec3f(0,0,0), n, u);

            for (uint k=0; k<profile.size(); k++) {
                Vec3f tmp = profile[k];
                m.mult(tmp, tmp);

                Pos->addValue(p+tmp);
                Norms->addValue(n);
                Colors->addValue(c);
            }

            for (uint k=1; k<=profile.size(); k++) {
                int j = k+1;
                if (k == profile.size()) j = 1;
                Indices->addValue(Ni);
                Indices->addValue(Ni+j);
                Indices->addValue(Ni+k);
                Nt+=3;
            }
        }

        Type->addValue(GL_TRIANGLES);
        Length->addValue(Nt); // caps triangles
    }

    SimpleMaterialRecPtr Mat = SimpleMaterial::create();
    GeometryRecPtr g = Geometry::create();
    g->setTypes(Type);
    g->setLengths(Length);
    g->setPositions(Pos);

    g->setNormals(Norms);
    g->setColors(Colors);
    g->setIndices(Indices);

    g->setMaterial(Mat);
    Mat->setLit(lit);

    setMesh(g);


    // test for ccw faces
    /*TriangleIterator it(getMesh());
	while (!it.isAtEnd()) {
        Vec3f p0 = Vec3f(it.getPosition(0));
        Vec3f p1 = Vec3f(it.getPosition(1));
        Vec3f p2 = Vec3f(it.getPosition(2));

        Vec3f n0 = it.getNormal(0);
        Vec3f n1 = it.getNormal(1);
        Vec3f n2 = it.getNormal(2);

        Vec3f np1 = (p1-p0).cross(p2-p0);
        Vec3f np2 = n0+n1+n2; np2.normalize();
        cout << " face orientation " << np1.dot(np2) << endl;

		++it;
	}*/
}
Exemplo n.º 11
0
void VRPhysicsManager::updatePhysObjects() {
    //mtx.try_lock();
    MLock lock(mtx);
    VRGlobals::get()->PHYSICS_FRAME_RATE = fps;

    for (auto o : OSGobjs) {
        if (auto so = o.second.lock()) {
            if (so->getPhysics()->isGhost()) so->updatePhysics();
        }
    }

    for (int j=dynamicsWorld->getNumCollisionObjects()-1; j>=0 ;j--) {
        btCollisionObject* obj = dynamicsWorld->getCollisionObjectArray()[j];
        body = btRigidBody::upcast(obj);
        if (body && body->getMotionState() && OSGobjs.count(body) == 1) { // TODO: refactor this!
            auto o = OSGobjs[body].lock();
            if (!o) continue;
            if (o->getPhysics()->isDynamic()) o->updateFromBullet();
            else o->getPhysics()->updateTransformation(o);
        }
    }

    //the soft bodies
    btSoftBodyArray arr = dynamicsWorld->getSoftBodyArray();
    //Patches
    VRTransformPtr soft_trans;
    btSoftBody* patch;
    for(int i = 0; i < arr.size() ;i++) { //for all soft bodies
        soft_trans = OSGobjs[arr[i]].lock(); //get the corresponding transform to this soft body
        if (!soft_trans) continue;
        patch = arr[i]; //the soft body
        if (soft_trans->getType() == "Sprite") {
            OSG::VRGeometryPtr geo = static_pointer_cast<OSG::VRGeometry>(soft_trans);
            OSG::VRGeometryPtr visualgeo = physics_visuals[patch]; //render the visual

            btSoftBody::tNodeArray&   nodes(patch->m_nodes);
            btSoftBody::tFaceArray&   faces(patch->m_faces);
            btSoftBody::tLinkArray&   links(patch->m_links);
            GeoPnt3fPropertyRecPtr visualpos = GeoPnt3fProperty::create();
            GeoUInt32PropertyRecPtr visualinds = GeoUInt32Property::create();
            GeoVec3fPropertyRecPtr visualnorms = GeoVec3fProperty::create();

            for (int i = 0; i<nodes.size(); i++) { //go through the nodes and copy positions to mesh positionarray
                    Vec3f p = VRPhysics::toVec3f(nodes[i].m_x);
                    OSG::Vec3f tmp;
                    visualpos->addValue(p);
                    Vec3f n = VRPhysics::toVec3f(nodes[i].m_n);
                    visualnorms->addValue( n );
            }

            for(int j=0;j<faces.size();++j) {
              btSoftBody::Node*   node_0=faces[j].m_n[0];
              btSoftBody::Node*   node_1=faces[j].m_n[1];
              btSoftBody::Node*   node_2=faces[j].m_n[2];
             const int indices[]={   int(node_0-&nodes[0]),
                                      int(node_1-&nodes[0]),
                                      int(node_2-&nodes[0])};
                visualinds->addValue(indices[0]);
                visualinds->addValue(indices[1]);
                visualinds->addValue(indices[2]);
           }
            GeoUInt32PropertyRecPtr vtypes = GeoUInt32Property::create();
            GeoUInt32PropertyRecPtr vlens = GeoUInt32Property::create();
            vtypes->addValue(GL_TRIANGLES);
            vlens->addValue(faces.size());
            vtypes->addValue(GL_LINES);
            vlens->addValue(links.size());

            visualgeo->setType(GL_TRIANGLES    );
            visualgeo->setPositions(visualpos);
            visualgeo->setIndices(visualinds);
            visualgeo->setNormals(visualnorms);

            if(geo->getPrimitive()->getType() == "Plane") { //only for plane soft bodies : directly apply nodes to vertices of geometry model
                //VRPlane* prim = (VRPlane*)geo->getPrimitive();
                GeoPnt3fPropertyRecPtr positions = GeoPnt3fProperty::create();
                GeoVec3fPropertyRecPtr norms = GeoVec3fProperty::create();
                GeoUInt32PropertyRecPtr inds = GeoUInt32Property::create();
                for (int i = 0; i<nodes.size(); i++) { //go through the nodes and copy positions to mesh positionarray
                    Vec3f p = VRPhysics::toVec3f(nodes[i].m_x);
                    positions->addValue(p);
                    Vec3f n = VRPhysics::toVec3f(nodes[i].m_n);
                    norms->addValue( n );
                }
                geo->setPositions(positions);
                geo->setNormals(norms);
           }

        /*   if(soft_trans->getPhysics()->getShape() == "Rope") { //only for Ropes

            }*/

        }
    }
}