Example #1
0
/***************************************************************************\
*                              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);
}
Example #2
0
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;
    }
}
Example #3
0
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;
}