/***************************************************************************\ * Field Set * \***************************************************************************/ void PhysicsTriMeshGeom::setGeometryNode(NodePtr& node) { PhysicsTriMeshGeomPtr tmpPtr(*this); GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if(geo!=NullFC) { calcVertexNormals(geo, deg2rad( 30)); separateProperties(geo); createSingleIndex(geo); GeoPositions3f::StoredFieldType* positions = GeoPositions3fPtr::dcast( geo->getPositions())->getFieldPtr(); GeoIndicesUI32::StoredFieldType* indices = GeoIndicesUI32Ptr::dcast( geo->getIndices())->getFieldPtr(); GeoNormals3f::StoredFieldType* normals = GeoNormals3fPtr::dcast( geo->getNormals())->getFieldPtr(); GeoPTypesPtr geoTypes = geo->getTypes(); bool triangles = false; //has to be some triangle soup! for( Int32 i=0; i < geoTypes->size(); ++i) { switch( geoTypes->getValue(i)) { case GL_TRIANGLES: triangles=true; break; case GL_TRIANGLE_STRIP: triangles=true; break; case GL_TRIANGLE_FAN: triangles=true; break; } } UInt32 vertexCount = GeoPositions3fPtr::dcast(geo->getPositions())->getSize(); UInt32 vertexStride = 3*sizeof(Real32); UInt32 indexCount = GeoIndicesUI32Ptr::dcast(geo->getIndices())->getSize(); UInt32 indexStride = 3*sizeof(UInt32); //pass the pointers to ODE if(tmpPtr->data) dGeomTriMeshDataDestroy(tmpPtr->data); tmpPtr->data = dGeomTriMeshDataCreate(); if(triangles) { dGeomTriMeshDataBuildSingle(tmpPtr->data, (Real32*)&positions->front(), vertexStride, vertexCount, (Int32*)&indices->front(), indexCount, indexStride/* just can't use this, (Real32*)&normals->front()*/); tmpPtr->setData(tmpPtr->data); /* use this method if you build with single precision dGeomTriMeshDataBuildSingle1(tmpPtr->data, (Real32*)&positions->front(), vertexStride, vertexCount, (Int32*)&indices->front(), indexCount, indexStride, (Real32*)&normals->front()); tmpPtr->setData(tmpPtr->data); */ } else { FWARNING(("No triangle mesh given to ODE! Convert to triangles first!\n")); tmpPtr->setData(tmpPtr->data); } } tmpPtr->geoNode=node; PhysicsTriMeshGeomBase::setGeometryNode(node); }
bool VerifyGraphOp::verifyIndexMap(GeometryPtr &geo, bool &repair) { repair = false; if(geo == NullFC) return true; if(geo->getIndices() == NullFC) return true; if(!geo->getMFIndexMapping()->empty()) return true; if(geo->getPositions() == NullFC) return true; UInt32 positions_size = geo->getPositions()->getSize(); UInt32 normals_size = 0; if(geo->getNormals() != NullFC) normals_size = geo->getNormals()->getSize(); UInt32 colors_size = 0; if(geo->getColors() != NullFC) colors_size = geo->getColors()->getSize(); UInt32 secondary_colors_size = 0; if(geo->getSecondaryColors() != NullFC) secondary_colors_size = geo->getSecondaryColors()->getSize(); UInt32 texccords_size = 0; if(geo->getTexCoords() != NullFC) texccords_size = geo->getTexCoords()->getSize(); UInt32 texccords1_size = 0; if(geo->getTexCoords1() != NullFC) texccords1_size = geo->getTexCoords1()->getSize(); UInt32 texccords2_size = 0; if(geo->getTexCoords2() != NullFC) texccords2_size = geo->getTexCoords2()->getSize(); UInt32 texccords3_size = 0; if(geo->getTexCoords3() != NullFC) texccords3_size = geo->getTexCoords3()->getSize(); /* printf("sizes: %u %u %u %u %u %u %u %u\n", positions_size, normals_size, colors_size, secondary_colors_size, texccords_size, texccords1_size, texccords2_size, texccords3_size); */ if((positions_size == normals_size || normals_size == 0) && (positions_size == colors_size || colors_size == 0) && (positions_size == secondary_colors_size || secondary_colors_size == 0) && (positions_size == texccords_size || texccords_size == 0) && (positions_size == texccords1_size || texccords1_size == 0) && (positions_size == texccords2_size || texccords2_size == 0) && (positions_size == texccords3_size || texccords3_size == 0) ) { UInt16 indexmap = 0; if(positions_size > 0) indexmap |= Geometry::MapPosition; if(normals_size > 0) indexmap |= Geometry::MapNormal; if(colors_size > 0) indexmap |= Geometry::MapColor; if(secondary_colors_size > 0) indexmap |= Geometry::MapSecondaryColor; if(texccords_size > 0) indexmap |= Geometry::MapTexCoords; if(texccords1_size > 0) indexmap |= Geometry::MapTexCoords1; if(texccords2_size > 0) indexmap |= Geometry::MapTexCoords2; if(texccords3_size > 0) indexmap |= Geometry::MapTexCoords3; beginEditCP(geo, Geometry::IndexMappingFieldMask); geo->editMFIndexMapping()->push_back(indexmap); endEditCP(geo, Geometry::IndexMappingFieldMask); repair = true; return false; } else { return false; } }
bool SplitGraphOp::splitNode(NodePtr& node, std::vector<NodePtr> &split) { //split it only if it is a non special geometry leaf if (!isLeaf(node) || isInExcludeList(node) || !node->getCore()->getType().isDerivedFrom(Geometry::getClassType())) return false; GeometryPtr geo = GeometryPtr::dcast(node->getCore()); if ( geo->getPositions() == NullFC || geo->getPositions()->size() == 0 || geo->getLengths() == NullFC || geo->getLengths()->size() == 0 || geo->getTypes() == NullFC || geo->getTypes()->size() == 0 ) return false; //get all center points std::vector<Pnt3f> centers; int ind; PrimitiveIterator it(geo); while (!it.isAtEnd()) { switch(it.getType()) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_TRIANGLE_STRIP: case GL_QUAD_STRIP: case GL_POLYGON: { Pnt3f center(0,0,0); for (UInt32 i=0; i<it.getLength(); i++) center+=Vec3f(it.getPosition(i)); center/=Real32(it.getLength()); centers.push_back(center); } break; case GL_TRIANGLES: ind=0; while(it.getLength()-ind>=3) { Pnt3f center(0,0,0); for (UInt32 i=0; i<3; i++, ind++) center+=Vec3f(it.getPosition(ind)); center/=3; centers.push_back(center); } break; case GL_QUADS: ind=0; while(it.getLength()-ind>=4) { Pnt3f center(0,0,0); for (UInt32 i=0; i<4; i++, ind++) center+=Vec3f(it.getPosition(ind)); center/=4; centers.push_back(center); } break; default: SWARNING << "SplitGraphOp::splitLeave: encountered " << "unknown primitive type " << it.getType() << ", ignoring!" << std::endl; break; } ++it; } std::vector<int> order; for (UInt32 i=0; i<centers.size(); i++) order.push_back(i); Pnt3fComparator comp(centers); std::sort(order.begin(), order.end(), comp); //now we need (centers.size()/_max_polygons) amount of new geometries int ngeos=int(ceil(double(centers.size())/double(_max_polygons))); if (ngeos<=1) return false; GeometryPtr *geos = new GeometryPtr[ngeos]; GeoPTypesPtr *types = new GeoPTypesPtr[ngeos]; GeoPLengthsPtr *lens = new GeoPLengthsPtr[ngeos]; GeoPositionsPtr *pnts = new GeoPositionsPtr[ngeos]; GeoNormalsPtr *normals = new GeoNormalsPtr[ngeos]; GeoColorsPtr *colors = new GeoColorsPtr[ngeos]; GeoColorsPtr *scolors = new GeoColorsPtr[ngeos]; GeoTexCoordsPtr *tex = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex1 = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex2 = new GeoTexCoordsPtr[ngeos]; GeoTexCoordsPtr *tex3 = new GeoTexCoordsPtr[ngeos]; GeoIndicesPtr *indices = new GeoIndicesPtr[ngeos]; int **pni = new int*[ngeos]; int **nni = new int*[ngeos]; int **cni = new int*[ngeos]; int **sni = new int*[ngeos]; int **tni = new int*[ngeos]; int **t1ni = new int*[ngeos]; int **t2ni = new int*[ngeos]; int **t3ni = new int*[ngeos]; for (Int32 i=0; i<ngeos; i++) { geos[i] = Geometry::create(); beginEditCP(geos[i]); // Keep open until the end geos[i]->setMaterial(geo->getMaterial()); if(geo->getMFIndexMapping() != NULL) geos[i]->editMFIndexMapping()->setValues(*(geo->getMFIndexMapping())); types[i] = GeoPTypesPtr::dcast(geo->getTypes()->getType().createFieldContainer()); lens[i] = GeoPLengthsPtr::dcast(geo->getLengths()->getType().createFieldContainer()); if (geo->getIndices()!=NullFC) { indices[i] = GeoIndicesPtr::dcast(geo->getIndices()->getType().createFieldContainer()); beginEditCP(indices[i]); // Keep open until the end } else indices[i] = NullFC; beginEditCP(types[i]); // Keep open until the end beginEditCP(lens[i]); // Keep open until the end setupAttr( GeoPositionsPtr , pnts , pni , getPositions ); setupAttr( GeoNormalsPtr , normals , nni , getNormals ); setupAttr( GeoColorsPtr , colors , cni , getColors ); setupAttr( GeoColorsPtr , scolors , sni , getSecondaryColors ); setupAttr( GeoTexCoordsPtr , tex , tni , getTexCoords ); setupAttr( GeoTexCoordsPtr , tex1 , t1ni , getTexCoords1 ); setupAttr( GeoTexCoordsPtr , tex2 , t2ni , getTexCoords2 ); setupAttr( GeoTexCoordsPtr , tex3 , t3ni , getTexCoords3 ); } ind=0; it.setToBegin(); while (!it.isAtEnd()) { switch(it.getType()) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_TRIANGLE_STRIP: case GL_QUAD_STRIP: case GL_POLYGON: { int geoIndex=order[ind]/_max_polygons; types[geoIndex]->push_back(it.getType()); lens[geoIndex]->push_back(it.getLength()); addPoints( 0 , it.getLength() ); ++ind; } break; case GL_TRIANGLES: { UInt32 i=0; while(it.getLength()-i>=3) { i+=3; ++ind; } } break; case GL_QUADS: { UInt32 i=0; while(it.getLength()-i>=4) { i+=4; ++ind; } } break; default: SWARNING << "SplitGraphOp::splitLeave: encountered " << "unknown primitive type " << it.getType() << ", ignoring!" << std::endl; break; } ++it; } ind=0; it.setToBegin(); while (!it.isAtEnd()) { switch(it.getType()) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_TRIANGLE_STRIP: case GL_QUAD_STRIP: case GL_POLYGON: { ++ind; } break; case GL_TRIANGLES: { UInt32 i=0; int geoIndex; while(it.getLength()-i>=3) { geoIndex = order[ind]/_max_polygons; if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_TRIANGLES) { int lind; if ((lind=lens[geoIndex]->size()-1)>=0) lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+3, lind); else lens[geoIndex]->push_back(3); } else { types[geoIndex]->push_back(GL_TRIANGLES); lens[geoIndex]->push_back(3); } addPoints( i ,3 ); i+=3; ++ind; } } break; case GL_QUADS: { UInt32 i=0; while(it.getLength()-i>=4) { i+=4; ++ind; } } break; default: SWARNING << "SplitGraphOp::splitLeave: encountered " << "unknown primitive type " << it.getType() << ", ignoring!" << std::endl; break; } ++it; } ind=0; it.setToBegin(); while (!it.isAtEnd()) { switch(it.getType()) { case GL_POINTS: case GL_LINES: case GL_LINE_STRIP: case GL_LINE_LOOP: case GL_TRIANGLE_FAN: case GL_TRIANGLE_STRIP: case GL_QUAD_STRIP: case GL_POLYGON: { ++ind; } break; case GL_TRIANGLES: { UInt32 i=0; while(it.getLength()-i>=3) { i+=3; ++ind; } } break; case GL_QUADS: { UInt32 i=0; int geoIndex; while(it.getLength()-i>=4) { geoIndex = order[ind]/_max_polygons; if (types[geoIndex]->size()>0 && types[geoIndex]->getValue(types[geoIndex]->size()-1) == GL_QUADS) { int lind; if ((lind=lens[geoIndex]->size()-1)>=0) lens[geoIndex]->setValue(lens[geoIndex]->getValue(lind)+4, lind); else lens[geoIndex]->push_back(4); } else { types[geoIndex]->push_back(GL_QUADS); lens[geoIndex]->push_back(4); } addPoints( i , 4 ); i+=4; ++ind; } } break; default: SWARNING << "SplitGraphOp::splitLeave: encountered " << "unknown primitive type " << it.getType() << ", ignoring!" << std::endl; break; } ++it; } for (Int32 i=0; i<ngeos; i++) { geos[i]->setTypes(types[i]); geos[i]->setLengths(lens[i]); geos[i]->setPositions(pnts[i]); // Now close the open FCs endEditCP(types[i]); endEditCP(lens[i]); endEditCP(pnts[i]); if (indices[i]!=NullFC) { geos[i]->setIndices(indices[i]); endEditCP(indices[i]); } if (normals[i]!=NullFC) { geos[i]->setNormals(normals[i]); endEditCP(normals[i]); } if (colors[i]!=NullFC) { geos[i]->setColors(colors[i]); endEditCP(colors[i]); } if (scolors[i]!=NullFC) { geos[i]->setSecondaryColors(scolors[i]); endEditCP(scolors[i]); } if (tex[i]!=NullFC) { geos[i]->setTexCoords(tex[i]); endEditCP(tex[i]); } if (tex1[i]!=NullFC) { geos[i]->setTexCoords1(tex1[i]); endEditCP(tex1[i]); } if (tex2[i]!=NullFC) { geos[i]->setTexCoords2(tex2[i]); endEditCP(tex2[i]); } if (tex3[i]!=NullFC) { geos[i]->setTexCoords3(tex3[i]); endEditCP(tex3[i]); } endEditCP(geos[i]); if (node->getParent()!=NullFC) { NodePtr n=Node::create(); beginEditCP(n, Node::CoreFieldMask); n->setCore(geos[i]); endEditCP (n, Node::CoreFieldMask); split.push_back(n); } } for (Int32 i=0; i<ngeos; i++) { if (pni[i]) delete [] pni[i]; if (nni[i]) delete [] nni[i]; if (cni[i]) delete [] cni[i]; if (sni[i]) delete [] sni[i]; if (tni[i]) delete [] tni[i]; if (t1ni[i]) delete [] t1ni[i]; if (t2ni[i]) delete [] t2ni[i]; if (t3ni[i]) delete [] t3ni[i]; } delete [] pni; delete [] nni; delete [] cni; delete [] sni; delete [] tni; delete [] t1ni; delete [] t2ni; delete [] t3ni; return true; }