OSG::NodePtr makePolygon(double pntData[][3], int numPoints) {

  OSG::GeometryPtr geoPtr  = OSG::Geometry::create();
  OSG::NodePtr     nodePtr = OSG::Node::create();

  GeoPositions3fPtr    pnts    = GeoPositions3f::create();
  GeoNormals3fPtr      norms   = GeoNormals3f::create();
  GeoTexCoords2fPtr    tex     = GeoTexCoords2f::create();
  GeoIndicesUI32Ptr    indices = GeoIndicesUI32::create();   
  GeoPLengthsUI32Ptr   lens    = GeoPLengthsUI32::create();  
  GeoPTypesUI8Ptr      types   = GeoPTypesUI8::create();     

  //Set up the properties according to the geometry defined above
  beginEditCP(pnts);
  beginEditCP(norms);
  
  for(int i = 0; i < numPoints; i++) 
    {
      pnts->push_back(Pnt3f(pntData[i][0],
                            pntData[i][1], 
                            pntData[i][2]));

      indices->push_back(2*i);

      norms->push_back(Vec3f(0.0, 0.0, pntData[i][2]));
      indices->push_back(2*i + 1);
    }

  endEditCP(pnts);
  endEditCP(norms);

  beginEditCP(types);
  beginEditCP(lens);
  types->push_back(GL_POLYGON);
  lens->push_back(numPoints);
  endEditCP(types);
  endEditCP(lens);

  beginEditCP(geoPtr);
  
  geoPtr->setMaterial(getDefaultMaterial());
  geoPtr->setPositions(pnts);
  geoPtr->setNormals(norms);
  geoPtr->setIndices(indices);
  
  geoPtr->editMFIndexMapping()->push_back(Geometry::MapPosition | 
                                          Geometry::MapNormal);
  
  geoPtr->setTypes(types);
  geoPtr->setLengths(lens);
  
  endEditCP(geoPtr);

  nodePtr->setCore(geoPtr);
  return nodePtr;
}
Exemple #2
0
// Create the coordinate cross
NodePtr createCoordinateCross()
{
    GeometryPtr geoPtr = Geometry::create();
    beginEditCP(geoPtr);
    {
        GeoPTypesUI8Ptr typesPtr = GeoPTypesUI8::create();
        typesPtr->push_back(GL_LINES);
        geoPtr->setTypes(typesPtr);

        GeoPLengthsUI32Ptr lensPtr = GeoPLengthsUI32::create();
        lensPtr->push_back(6);
        geoPtr->setLengths(lensPtr);

        GeoPositions3fPtr posPtr = GeoPositions3f::create();
        posPtr->push_back(Vec3f(-0.1f, 0.f, 0.f));
        posPtr->push_back(Vec3f(1.f, 0.f, 0.f));
        posPtr->push_back(Vec3f(0.f, -0.1f, 0.f));
        posPtr->push_back(Vec3f(0.f, 1.f, 0.f));
        posPtr->push_back(Vec3f(0.f, 0.f, -0.1f));
        posPtr->push_back(Vec3f(0.f, 0.f, 1.f));
        geoPtr->setPositions(posPtr);

        GeoColors3fPtr colorsPtr = GeoColors3f::create();
        colorsPtr->push_back(Color3f(1.f, 0.f, 0.f));
        colorsPtr->push_back(Color3f(0.f, 1.f, 0.f));
        colorsPtr->push_back(Color3f(0.f, 0.f, 1.f));
        geoPtr->setColors(colorsPtr);

        GeoIndicesUI32Ptr indicesPtr = GeoIndicesUI32::create();
        // X Axis
        indicesPtr->push_back(0);
        indicesPtr->push_back(0);
        indicesPtr->push_back(1);
        indicesPtr->push_back(0);
        // Y Axis
        indicesPtr->push_back(2);
        indicesPtr->push_back(1);
        indicesPtr->push_back(3);
        indicesPtr->push_back(1);
        // Z Axis
        indicesPtr->push_back(4);
        indicesPtr->push_back(2);
        indicesPtr->push_back(5);
        indicesPtr->push_back(2);
        geoPtr->setIndices(indicesPtr);

        geoPtr->editMFIndexMapping()->clear();
        geoPtr->editMFIndexMapping()->push_back(Geometry::MapPosition);
        geoPtr->editMFIndexMapping()->push_back(Geometry::MapColor);

        SimpleMaterialPtr matPtr = SimpleMaterial::create();
        geoPtr->setMaterial(matPtr);
    }
    endEditCP(geoPtr);

    NodePtr nodePtr = Node::create();
    beginEditCP(nodePtr, Node::CoreFieldMask);
    {
        nodePtr->setCore(geoPtr);
    }
    endEditCP(nodePtr, Node::CoreFieldMask);

    return nodePtr;
}
Exemple #3
0
// Create the metrics
NodePtr createMetrics(TextFace *face, Real32 scale, const TextLayoutParam &layoutParam,
                      const TextLayoutResult &layoutResult)
{
    GeometryPtr geoPtr = Geometry::create();
    beginEditCP(geoPtr);
    {
        GeoPTypesUI8Ptr typesPtr = GeoPTypesUI8::create();
        geoPtr->setTypes(typesPtr);

        GeoPLengthsUI32Ptr lensPtr = GeoPLengthsUI32::create();
        geoPtr->setLengths(lensPtr);

        GeoPositions3fPtr posPtr = GeoPositions3f::create();
        geoPtr->setPositions(posPtr);

        GeoColors3fPtr colorsPtr = GeoColors3f::create();
        colorsPtr->push_back(Color3f(0.f, 0.f, 1.f));
        colorsPtr->push_back(Color3f(1.f, 0.f, 0.f));
        colorsPtr->push_back(Color3f(0.f, 1.f, 0.f));
        colorsPtr->push_back(Color3f(1.f, 1.f, 0.f));
        geoPtr->setColors(colorsPtr);

        GeoIndicesUI32Ptr indicesPtr = GeoIndicesUI32::create();
        geoPtr->setIndices(indicesPtr);

        UInt32 i, numGlyphs = layoutResult.getNumGlyphs();
        for (i = 0; i < numGlyphs; ++i)
        {
            const TextGlyph &glyph = face->getGlyph(layoutResult.indices[i]);
            typesPtr->push_back(GL_LINE_LOOP);
            lensPtr->push_back(4);
            const Vec2f &pos = layoutResult.positions[i];
            Real32 left = pos.x() * scale;
            Real32 right = (pos.x() + glyph.getWidth()) * scale;
            Real32 top = pos.y() * scale;
            Real32 bottom = (pos.y() - glyph.getHeight()) * scale;
            UInt32 posOffset = posPtr->size();
            posPtr->push_back(Vec3f(left, bottom, 0.f));
            posPtr->push_back(Vec3f(right, bottom, 0.f));
            posPtr->push_back(Vec3f(right, top, 0.f));
            posPtr->push_back(Vec3f(left, top, 0.f));
            indicesPtr->push_back(posOffset);
            indicesPtr->push_back(0);
            indicesPtr->push_back(posOffset + 1);
            indicesPtr->push_back(0);
            indicesPtr->push_back(posOffset + 2);
            indicesPtr->push_back(0);
            indicesPtr->push_back(posOffset + 3);
            indicesPtr->push_back(0);
        }

        // Bounding box
        Vec2f lowerLeft, upperRight;
        face->calculateBoundingBox(layoutResult, lowerLeft, upperRight);
        typesPtr->push_back(GL_LINE_LOOP);
        lensPtr->push_back(4);
        Real32 left = lowerLeft.x() * scale;
        Real32 right = upperRight.x() * scale;
        Real32 top = upperRight.y() * scale;
        Real32 bottom = lowerLeft.y() * scale;
        UInt32 posOffset = posPtr->size();
        posPtr->push_back(Vec3f(left, bottom, 0.f));
        posPtr->push_back(Vec3f(right, bottom, 0.f));
        posPtr->push_back(Vec3f(right, top, 0.f));
        posPtr->push_back(Vec3f(left, top, 0.f));
        indicesPtr->push_back(posOffset);
        indicesPtr->push_back(1);
        indicesPtr->push_back(posOffset + 1);
        indicesPtr->push_back(1);
        indicesPtr->push_back(posOffset + 2);
        indicesPtr->push_back(1);
        indicesPtr->push_back(posOffset + 3);
        indicesPtr->push_back(1);

        // Text bounds & Line bounds
        Vec2f pos, textPos, offset;
        if (layoutParam.horizontal == true)
        {
            Real32 lineHeight = face->getHoriAscent() - face->getHoriDescent();
            Real32 spacing = layoutParam.spacing * lineHeight;
            if (layoutParam.topToBottom == true)
            {
                switch (layoutParam.minorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                        break;
                    case TextLayoutParam::ALIGN_FIRST:
                        pos[1] = textPos[1] = face->getHoriAscent();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        pos[1] = textPos[1] = (spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        pos[1] = textPos[1] = spacing * (layoutResult.lineBounds.size() - 1) + lineHeight;
                        break;
                }
                offset.setValues(0.f, -spacing);
            }
            else
            {
                switch (layoutParam.minorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                        pos[1] = lineHeight;
                        textPos[1] = spacing * (layoutResult.lineBounds.size() - 1) + lineHeight;
                        break;
                    case TextLayoutParam::ALIGN_FIRST:
                        pos[1] = face->getHoriAscent();
                        textPos[1] = spacing * (layoutResult.lineBounds.size() - 1) + face->getHoriAscent();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        pos[1] = -(spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f + lineHeight;
                        textPos[1] = (spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        pos[1] = -spacing * (layoutResult.lineBounds.size() - 1);
                        break;
                }
                offset.setValues(0.f, spacing);
            }
        }
        else
        {
            Real32 lineHeight = face->getVertDescent() - face->getVertAscent();
            Real32 spacing = layoutParam.spacing * lineHeight;
            if (layoutParam.leftToRight == true)
            {
                switch (layoutParam.minorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                        break;
                    case TextLayoutParam::ALIGN_FIRST:
                        pos[0] = textPos[0] = face->getVertAscent();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        pos[0] = textPos[0] = -(spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        pos[0] = textPos[0] = -spacing * (layoutResult.lineBounds.size() - 1) - lineHeight;
                        break;
                }
                offset.setValues(spacing, 0.f);
            }
            else
            {
                switch (layoutParam.minorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                        pos[0] = -lineHeight;
                        textPos[0] = -spacing * (layoutResult.lineBounds.size() - 1) - lineHeight;
                        break;
                    case TextLayoutParam::ALIGN_FIRST:
                        pos[0] = -face->getVertDescent();
                        textPos[0] = -spacing * (layoutResult.lineBounds.size() - 1) -face->getVertDescent();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        pos[0] = (spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f - lineHeight;
                        textPos[0] = -(spacing * (layoutResult.lineBounds.size() - 1) + lineHeight) / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        pos[0] = spacing * (layoutResult.lineBounds.size() - 1);
                        break;
                }
                offset.setValues(-spacing, 0.f);
            }
        }

        typesPtr->push_back(GL_LINE_LOOP);
        lensPtr->push_back(4);
        left = textPos.x();
        top = textPos.y();
        if (layoutParam.horizontal == true)
            if (layoutParam.leftToRight == true)
                switch (layoutParam.majorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                    case TextLayoutParam::ALIGN_FIRST:
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        left -= layoutResult.textBounds.x() / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        left -= layoutResult.textBounds.x();
                        break;
                }
            else
                switch (layoutParam.majorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                    case TextLayoutParam::ALIGN_FIRST:
                        left -= layoutResult.textBounds.x();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        left -= layoutResult.textBounds.x() / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        break;
                }
        else
            if (layoutParam.topToBottom == true)
                switch (layoutParam.majorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                    case TextLayoutParam::ALIGN_FIRST:
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        top += layoutResult.textBounds.y() / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        top += layoutResult.textBounds.y();
                        break;
                }
            else
                switch (layoutParam.majorAlignment)
                {
                    case TextLayoutParam::ALIGN_BEGIN:
                    case TextLayoutParam::ALIGN_FIRST:
                        top += layoutResult.textBounds.y();
                        break;
                    case TextLayoutParam::ALIGN_MIDDLE:
                        top += layoutResult.textBounds.y() / 2.f;
                        break;
                    case TextLayoutParam::ALIGN_END:
                        break;
                }
        left *= scale;
        right = left + layoutResult.textBounds.x() * scale;
        top *= scale;
        bottom = top - layoutResult.textBounds.y() * scale;
        posOffset = posPtr->size();
        posPtr->push_back(Vec3f(left, bottom, 0.f));
        posPtr->push_back(Vec3f(right, bottom, 0.f));
        posPtr->push_back(Vec3f(right, top, 0.f));
        posPtr->push_back(Vec3f(left, top, 0.f));
        indicesPtr->push_back(posOffset);
        indicesPtr->push_back(3);
        indicesPtr->push_back(posOffset + 1);
        indicesPtr->push_back(3);
        indicesPtr->push_back(posOffset + 2);
        indicesPtr->push_back(3);
        indicesPtr->push_back(posOffset + 3);
        indicesPtr->push_back(3);

        vector<Vec2f>::const_iterator lbIt;
        for (lbIt = layoutResult.lineBounds.begin(); lbIt != layoutResult.lineBounds.end(); ++lbIt)
        {
            typesPtr->push_back(GL_LINE_LOOP);
            lensPtr->push_back(4);
            Real32 left = pos.x();
            Real32 top = pos.y();
            if (layoutParam.horizontal == true)
                if (layoutParam.leftToRight == true)
                    switch (layoutParam.majorAlignment)
                    {
                        case TextLayoutParam::ALIGN_BEGIN:
                        case TextLayoutParam::ALIGN_FIRST:
                            break;
                        case TextLayoutParam::ALIGN_MIDDLE:
                            left -= lbIt->x() / 2.f;
                            break;
                        case TextLayoutParam::ALIGN_END:
                            left -= lbIt->x();
                            break;
                    }
                else
                    switch (layoutParam.majorAlignment)
                    {
                        case TextLayoutParam::ALIGN_BEGIN:
                        case TextLayoutParam::ALIGN_FIRST:
                            left -= lbIt->x();
                            break;
                        case TextLayoutParam::ALIGN_MIDDLE:
                            left -= lbIt->x() / 2.f;
                            break;
                        case TextLayoutParam::ALIGN_END:
                            break;
                    }
            else
                if (layoutParam.topToBottom == true)
                    switch (layoutParam.majorAlignment)
                    {
                        case TextLayoutParam::ALIGN_BEGIN:
                        case TextLayoutParam::ALIGN_FIRST:
                            break;
                        case TextLayoutParam::ALIGN_MIDDLE:
                            top += lbIt->y() / 2.f;
                            break;
                        case TextLayoutParam::ALIGN_END:
                            top += lbIt->y();
                            break;
                    }
                else
                    switch (layoutParam.majorAlignment)
                    {
                        case TextLayoutParam::ALIGN_BEGIN:
                        case TextLayoutParam::ALIGN_FIRST:
                            top += lbIt->y();
                            break;
                        case TextLayoutParam::ALIGN_MIDDLE:
                            top += lbIt->y() / 2.f;
                            break;
                        case TextLayoutParam::ALIGN_END:
                            break;
                    }
            left *= scale;
            Real32 right = left + lbIt->x() * scale;
            top *= scale;
            Real32 bottom = top - lbIt->y() * scale;
            UInt32 posOffset = posPtr->size();
            posPtr->push_back(Vec3f(left, bottom, 0.f));
            posPtr->push_back(Vec3f(right, bottom, 0.f));
            posPtr->push_back(Vec3f(right, top, 0.f));
            posPtr->push_back(Vec3f(left, top, 0.f));
            indicesPtr->push_back(posOffset);
            indicesPtr->push_back(2);
            indicesPtr->push_back(posOffset + 1);
            indicesPtr->push_back(2);
            indicesPtr->push_back(posOffset + 2);
            indicesPtr->push_back(2);
            indicesPtr->push_back(posOffset + 3);
            indicesPtr->push_back(2);

            typesPtr->push_back(GL_LINE_STRIP);
            lensPtr->push_back(2);
            posOffset = posPtr->size();
            if (layoutParam.horizontal == true)
            {
                Real32 base = top - face->getHoriAscent() * scale;
                posPtr->push_back(Vec3f(left, base, 0.f));
                posPtr->push_back(Vec3f(right, base, 0.f));
            }
            else
            {
                Real32 base = left - face->getVertAscent() * scale;
                posPtr->push_back(Vec3f(base, top, 0.f));
                posPtr->push_back(Vec3f(base, bottom, 0.f));
            }
            indicesPtr->push_back(posOffset);
            indicesPtr->push_back(2);
            indicesPtr->push_back(posOffset + 1);
            indicesPtr->push_back(2);
            pos += offset;
        }

        geoPtr->editMFIndexMapping()->clear();
        geoPtr->editMFIndexMapping()->push_back(Geometry::MapPosition);
        geoPtr->editMFIndexMapping()->push_back(Geometry::MapColor);

        SimpleMaterialPtr matPtr = SimpleMaterial::create();
        geoPtr->setMaterial(matPtr);
    }
    endEditCP(geoPtr);

    NodePtr nodePtr = Node::create();
    beginEditCP(nodePtr, Node::CoreFieldMask);
    {
        nodePtr->setCore(geoPtr);
    }
    endEditCP(nodePtr, Node::CoreFieldMask);

    return nodePtr;
}
// Initialize GLUT & OpenSG and set up the scene
int main(int argc, char **argv)
{
    // OSG init
    osgInit(argc,argv);

    // GLUT init
    int winid = setupGLUT(&argc, argv);

    // the connection between GLUT and OpenSG
    GLUTWindowPtr gwin= GLUTWindow::create();
    gwin->setId(winid);
    gwin->init();

    // create the scene
     
    /*
        In the previous example, the colors and positions used the same
        indices. That might not always be the preferred way, and it might not
        make sense for other properties, e.g. normals.
        
        It is possible to assign a different index for every property. See the
        indices section below for details.
    */
    
    /*
        The initial setup is the same as in the single indexed geometry...
    */
    GeoPTypesPtr type = GeoPTypesUI8::create();        
    beginEditCP(type, GeoPTypesUI8::GeoPropDataFieldMask);
    {
        type->push_back(GL_POLYGON  );
        type->push_back(GL_TRIANGLES);
        type->push_back(GL_QUADS    );
    }
    endEditCP  (type, GeoPTypesUI8::GeoPropDataFieldMask);

    GeoPLengthsPtr lens = GeoPLengthsUI32::create();    
    beginEditCP(lens, GeoPLengthsUI32::GeoPropDataFieldMask);
    {
        lens->push_back(4);
        lens->push_back(6);
        lens->push_back(8);
    }
    endEditCP  (lens, GeoPLengthsUI32::GeoPropDataFieldMask);
       
    GeoPositions3fPtr pnts = GeoPositions3f::create();
    beginEditCP(pnts, GeoPositions3f::GeoPropDataFieldMask);
    {
        // the base
        pnts->push_back(Pnt3f(-1, -1, -1));
        pnts->push_back(Pnt3f(-1, -1,  1));
        pnts->push_back(Pnt3f( 1, -1,  1));
        pnts->push_back(Pnt3f( 1, -1, -1));

        // the roof base
        pnts->push_back(Pnt3f(-1,  0, -1));
        pnts->push_back(Pnt3f(-1,  0,  1));
        pnts->push_back(Pnt3f( 1,  0,  1));
        pnts->push_back(Pnt3f( 1,  0, -1));

        // the gable
        pnts->push_back(Pnt3f( 0,  1, -1));
        pnts->push_back(Pnt3f( 0,  1,  1));
    }
    endEditCP  (pnts, GeoPositions3f::GeoPropDataFieldMask);
   
    GeoColors3fPtr colors = GeoColors3f::create();
    beginEditCP(colors, GeoColors3f::GeoPropDataFieldMask);
    {
        colors->push_back(Color3f(1, 1, 0));
        colors->push_back(Color3f(1, 0, 0));
        colors->push_back(Color3f(1, 0, 0));
        colors->push_back(Color3f(1, 1, 0));
        colors->push_back(Color3f(0, 1, 1));
        colors->push_back(Color3f(1, 0, 1));
    }
    endEditCP  (colors, GeoPositions3f::GeoPropDataFieldMask);

    /*
        A new property: normals.
        
        They are used for lighting calculations and have to point away from the
        surface. Normals are standard vectors.
    */
    GeoNormals3fPtr norms = GeoNormals3f::create();
    beginEditCP(norms, GeoNormals3f::GeoPropDataFieldMask);
    {
        norms->push_back(Vec3f(-1,  0,  0));
        norms->push_back(Vec3f( 1,  0,  0));
        norms->push_back(Vec3f( 0, -1,  0));
        norms->push_back(Vec3f( 0,  1,  0));
        norms->push_back(Vec3f( 0,  0, -1));
        norms->push_back(Vec3f( 0,  0,  1));
    }
    endEditCP  (norms, GeoNormals3f::GeoPropDataFieldMask);
    
  
    /*
        To use different indices for different attributes they have to be
        specified. This is done within the single index property, by using more
        than one index per vertex.
        
        In this case every vertex reads multiple indices from the Indices
        property. The meaning of every index is defined by the indexMapping
        given below.
    */
    GeoIndicesUI32Ptr indices = GeoIndicesUI32::create();
    beginEditCP(indices, GeoIndicesUI32::GeoPropDataFieldMask);
    {
        // indices for the polygon
        indices->push_back(0);   // position index
        indices->push_back(3);   // color/normal index
        indices->push_back(1);   // position index
        indices->push_back(3);   // color/normal index
        indices->push_back(2);   // position index
        indices->push_back(3);   // color/normal index
        indices->push_back(3);   // position index
        indices->push_back(3);   // color/normal index
       
        // indices for the triangles
        indices->push_back(7);   // position index
        indices->push_back(4);   // color/normal index
        indices->push_back(4);   // position index
        indices->push_back(4);   // color/normal index
        indices->push_back(8);   // position index
        indices->push_back(4);   // color/normal index

        indices->push_back(5);   // position index
        indices->push_back(5);   // color/normal index
        indices->push_back(6);   // position index
        indices->push_back(5);   // color/normal index
        indices->push_back(9);   // position index
        indices->push_back(5);   // color/normal index
        
        // indices for the quads
        indices->push_back(1);   // position index
        indices->push_back(5);   // color/normal index
        indices->push_back(2);   // position index
        indices->push_back(5);   // color/normal index
        indices->push_back(6);   // position index
        indices->push_back(5);   // color/normal index
        indices->push_back(5);   // position index
        indices->push_back(5);   // color/normal index

        indices->push_back(3);   // position index
        indices->push_back(4);   // color/normal index
        indices->push_back(0);   // position index
        indices->push_back(4);   // color/normal index
        indices->push_back(4);   // position index
        indices->push_back(4);   // color/normal index
        indices->push_back(7);   // position index
        indices->push_back(4);   // color/normal index
    }
    endEditCP  (indices, GeoIndicesUI32::GeoPropDataFieldMask);
    
    /*
       Put it all together into a Geometry NodeCore.
    */
    GeometryPtr geo=Geometry::create();
    beginEditCP(geo, Geometry::TypesFieldMask          |
                     Geometry::LengthsFieldMask        |
                     Geometry::IndicesFieldMask        |
                     Geometry::IndexMappingFieldMask   |
                     Geometry::PositionsFieldMask      |
                     Geometry::NormalsFieldMask        |
                     Geometry::ColorsFieldMask         |
                     Geometry::MaterialFieldMask       );
    {
        geo->setTypes    (type);
        geo->setLengths  (lens);
        geo->setIndices  (indices);
        
        /*
             The meaning of the different indices is given by the indexMapping
             field. 

             If contains an entry that defines which index for a vertex
             selects which attribute. In this example the first index selects
             the positions, the second is used for colors and normals.

             The number of elements in the indexMapping field defines the
             number of indices used for every vertex.
        */
        geo->editMFIndexMapping()->push_back(Geometry::MapPosition   );
        geo->editMFIndexMapping()->push_back(Geometry::MapColor    |
                                             Geometry::MapNormal     );
         
        geo->setPositions(pnts  );
        geo->setColors   (colors);
        geo->setNormals  (norms );
        
        /*
            Use a lit material this time, to show the effect of the normals.
        */
        geo->setMaterial (getDefaultMaterial());   
    }
    endEditCP  (geo, Geometry::TypesFieldMask          |
                     Geometry::LengthsFieldMask        |
                     Geometry::IndicesFieldMask        |
                     Geometry::IndexMappingFieldMask   |
                     Geometry::PositionsFieldMask      |
                     Geometry::NormalsFieldMask        |
                     Geometry::ColorsFieldMask         |
                     Geometry::MaterialFieldMask       );
    
    // put the geometry core into a node
    NodePtr n = Node::create();
    beginEditCP(n, Node::CoreFieldMask);
    {
        n->setCore(geo);
    }
    endEditCP  (n, Node::CoreFieldMask);
    
    // add a transformation to make it move     
    NodePtr scene = Node::create();  
    trans = Transform::create();
    beginEditCP(scene, Node::CoreFieldMask | Node::ChildrenFieldMask  );
    {
        scene->setCore(trans);
        scene->addChild(n);
    }
    endEditCP  (scene, Node::CoreFieldMask | Node::ChildrenFieldMask  );
 

    // create the SimpleSceneManager helper
    mgr = new SimpleSceneManager;

    // tell the manager what to manage
    mgr->setWindow(gwin );
    mgr->setRoot  (scene);

    // show the whole scene
    mgr->showAll();

    // GLUT main loop
    glutMainLoop();

    return 0;
}
GeometryPtr PerformerLoader::traverseGSet(NodePtr node, pfGeoSet *gset)
{
    FINFO(("PerformerLoader::traverseGSet: traversing %p: ", gset));
    
    if(gset->getType()->isDerivedFrom(pfGeoArray::getClassType()))
    {
        return traverseGArray(node, dynamic_cast<pfGeoArray*>(gset));
    }
    
    pfGeoState *gstate = gset->getGState();

    int primtype, primcount, vertcount;

    primtype = gset->getPrimType();
    primcount = gset->getNumPrims();

    FINFO(("pt %d, pc %d ", primtype, primcount));

    int lencount, *lenlist;
    if (lenlist = gset->getPrimLengths())
	{
        int i;
	    for (i = 0, lencount = 0; i < primcount; i++)
		    lencount += PF_ABS(lenlist[i]);
	}	
    
    // Map Performer to OpenGL primtype
    UInt32 oprimtype = GL_POINTS;
    
    static int pprimtypes[] = { PFGS_POINTS, PFGS_LINES, PFGS_TRIS,
                                PFGS_QUADS, PFGS_LINESTRIPS, PFGS_TRISTRIPS, 
                                PFGS_TRIFANS, PFGS_POLYS, 
                                PFGS_FLAT_LINESTRIPS, PFGS_FLAT_TRISTRIPS, 
                                PFGS_FLAT_TRIFANS, -1};
    static int oprimtypes[] = { GL_POINTS, GL_LINES, GL_TRIANGLES,
                                GL_QUADS, GL_LINE_STRIP, GL_TRIANGLE_STRIP, 
                                GL_TRIANGLE_FAN, GL_POLYGON,
                                GL_LINE_STRIP, GL_TRIANGLE_STRIP, 
                                GL_TRIANGLE_FAN };
    
    for (UInt16 i = 0; pprimtypes[i] != -1; ++i)
        if(pprimtypes[i] == primtype)
            oprimtype = oprimtypes[i];
    
    int cn_buffer = 0;
    
    switch (primtype)
	{
	    case PFGS_POINTS:       vertcount = primcount;
                                primcount = 1;
		                        break;
	    case PFGS_LINES:        vertcount = primcount * 2;
		                        primcount = 1;
		                        break;
	    case PFGS_TRIS:         vertcount = primcount * 3;
		                        primcount = 1;
		                        break;
	    case PFGS_QUADS:        vertcount = primcount * 4;
		                        primcount = 1;
		                        break;
	    case PFGS_LINESTRIPS:
	    case PFGS_TRISTRIPS:
	    case PFGS_TRIFANS:
	    case PFGS_POLYS:        vertcount = lencount;
		                        break;
	    case PFGS_FLAT_LINESTRIPS:
            FDEBUG(("PerformerLoader::traverseGSet: found "
                      "primitive PFGS_FLAT_LINESTRIPS, will split into"
                      "individual lines!\n"));
            cn_buffer = 1;
            vertcount = lencount;
            break;
	    case PFGS_FLAT_TRISTRIPS:
            FDEBUG(("PerformerLoader::traverseGSet: found "
                      "primitive PFGS_FLAT_TRISTRIPS!\n"));
            cn_buffer = 2;
            vertcount = lencount;
            break;
	    case PFGS_FLAT_TRIFANS:
            FDEBUG(("PerformerLoader::traverseGSet: found "
                      "primitive PFGS_FLAT_TRIFANS!\n"));
            cn_buffer = 2;
            vertcount = lencount;
            break;
	}

    FINFO(("vc %d ", vertcount));
    
    // Fill the Geometry
    GeometryPtr ogeo = Geometry::create();
    
    beginEditCP(ogeo);
    
    if(gstate)
    {
        ogeo->setMaterial(traverseGState(node, gstate));       
    }
    else
    {
        ogeo->setMaterial(NullFC);
    }

    GeoPTypesPtr otypes = GeoPTypesUI8::create();

    beginEditCP(otypes);
     
    if (lenlist = gset->getPrimLengths())
	{
        GeoPLengthsUI32Ptr olens  = GeoPLengthsUI32::create();
        beginEditCP(olens);
	    for (int i = 0; i < primcount; i++)
        {
            otypes->push_back(oprimtype);
            olens->push_back(lenlist[i]);
        }
        endEditCP(olens);
        ogeo->setLengths(olens);
	}	
    else
    {
        otypes->push_back(oprimtype);
        lenlist = &vertcount;
        lencount = vertcount;
        if(primcount != 1)
            FWARNING(("PerformerLoader::traverseGSet: No lens, but "
                      "primcount=%d.\n", primcount));
    }

    endEditCP(otypes);

    ogeo->setTypes(otypes);
    
    // Convert the geo attributes

    int pmin, pmax;
    pfVec3 *pverts;
    ushort *pinds;
    
    GeoPositions3fPtr opos = GeoPositions3f::create();
    GeoIndicesUI16Ptr oind = GeoIndicesUI16::create();
    
    beginEditCP(opos);
    beginEditCP(oind);
       
    gset->getAttrLists(PFGS_COORD3, (void**)&pverts, &pinds);
    if(pverts)
    {
        if(pinds)
        {
            FINFO(("Vi %d-%d ", pmin, pmax));
            
            gset->getAttrRange(PFGS_COORD3, &pmin, &pmax);
            
            for(UInt32 i = 0; i < pmax+1; ++i)
                opos->push_back(Vec3f(pverts[i].vec));
            
            for(UInt32 i = 0; i < vertcount; ++i)
                oind->push_back(pinds[i]);
        }
        else
        {            
            FINFO(("V "));
            
            for(UInt32 i = 0; i < vertcount; ++i)
                opos->push_back(Vec3f(pverts[i].vec));           
        }
    }
    endEditCP(opos);
    endEditCP(oind);
    
    ogeo->setPositions(opos);
    
    if(oind->size())
    {
        ogeo->setIndices(oind);
    }
    else
    {
        subRefCP(oind);
    }
 
    int bind;
    
   
    // Normals
    if((bind = gset->getAttrBind(PFGS_NORMAL3)) != PFGS_OFF)
    {
        if(bind == PFGS_PER_PRIM)
        {
            FNOTICE(("PerformerLoader::traverseGSet: found PER_PRIM binding "
                     "for normals, ignoring them.\n"));
        }
        else if(bind == PFGS_OVERALL)
        {
            FINFO(("NO "));
            GeoNormals3fPtr onorm = GeoNormals3f::create();

            beginEditCP(onorm);
            pfVec3 *pnorms;
            gset->getAttrLists(PFGS_NORMAL3, (void**)&pnorms, &pinds);

            if(pnorms)
            {
                Vec3f c;
                c.setValues(pnorms[0].vec[0], pnorms[0].vec[1],
                                pnorms[0].vec[2]);
#if 0 // This assumes a single normal is used as overall. Not true for 1.x
                onorm->getField().push_back(c);
#else
                for(int i = 0; i < vertcount; ++i)
                    onorm->getField().push_back(c);
#endif            
            }

            endEditCP(onorm);

            ogeo->setNormals(onorm);
        }
        else
        {
            GeoNormals3fPtr onorm = GeoNormals3f::create();

            beginEditCP(onorm);

            pfVec3 *pnorms;
            ushort *pninds;
             
            gset->getAttrLists(PFGS_NORMAL3, (void**)&pnorms, &pninds);
            
            if(pnorms)
            {
                if(pninds)
                {
                    int pcmin, pcmax;
                    gset->getAttrRange(PFGS_NORMAL3, &pcmin, &pcmax);
            
                    FINFO(("NI %d-%d ", pcmin, pcmax));

                    // Check indices
                    if(pcmax != pmax)   
                        FWARNING(("Normal pmax %d != pmax %d!\n", 
                                    pcmax, pmax));
                                    
                    for(int i = 0; i < pcmax; ++i)
                    {
                        if(pinds[i] != pninds[i])
                            FWARNING(("Normal Index %d (%d) != vind (%d)!\n",
                                i, pninds[i], pinds[i]));
                    }
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Vec3f c;
                        c.setValues(pnorms[0].vec[0], pnorms[0].vec[1],
                                    pnorms[0].vec[2]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            onorm->getField().push_back(c);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Vec3f c;
                            c.setValues(pnorms[ind].vec[0], 
                                        pnorms[ind].vec[1],
                                        pnorms[ind].vec[2]);
                            onorm->getField().push_back(c);
                        }
                    }
                }
                else
                {
                    FINFO(("N "));
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Vec3f c;
                        c.setValues(pnorms[0].vec[0], pnorms[0].vec[1],
                                    pnorms[0].vec[2]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            onorm->getField().push_back(c);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Vec3f c;
                            c.setValues(pnorms[ind].vec[0], 
                                        pnorms[ind].vec[1],
                                        pnorms[ind].vec[2]);
                            onorm->getField().push_back(c);
                        }
                    }
                }
            }    
            endEditCP(onorm);

            ogeo->setNormals(onorm);
        }
    }

    // Colors
    if((bind = gset->getAttrBind(PFGS_COLOR4)) != PFGS_OFF)
    {
        if(bind == PFGS_PER_PRIM)
        {
            FNOTICE(("PerformerLoader::traverseGSet: found PER_PRIM binding "
                     "for colors, ignoring them.\n"));
        }
        else if(bind == PFGS_OVERALL)
        {
            FINFO(("CO "));
            GeoColors4fPtr ocols = GeoColors4f::create();

            beginEditCP(ocols);
            pfVec4 *pcols;
            gset->getAttrLists(PFGS_COLOR4, (void**)&pcols, &pinds);

            if(pcols)
            {
                Color4f c;
                c.setValuesRGBA(pcols[0].vec[0], pcols[0].vec[1],
                                pcols[0].vec[2], pcols[0].vec[3]);
#if 0 // This assumes a single colors is used as overall. Not true for 1.x
                ocols->getField().push_back(c);
#else
                for(int i = 0; i < vertcount; ++i)
                    ocols->getField().push_back(c);
#endif            
            }

            endEditCP(ocols);

            ogeo->setColors(ocols);
        }
        else
        {
            GeoColors4fPtr ocols = GeoColors4f::create();

            beginEditCP(ocols);

            pfVec4 *pcols;
            ushort *pcinds;
             
            gset->getAttrLists(PFGS_COLOR4, (void**)&pcols, &pcinds);
            
            if(pcols)
            {
                if(pcinds)
                {
                    int pcmin, pcmax;
                    gset->getAttrRange(PFGS_COLOR4, &pcmin, &pcmax);
                    
                    FINFO(("CI %d-%d ", pcmin, pcmax));

                    if(pcmax != pmax)   
                        FWARNING(("Color pmax %d != pmax %d!\n", 
                                    pcmax, pmax));
                                    
                    for(int i = 0; i < pcmax; ++i)
                    {
                        if(pinds[i] != pcinds[i])
                            FWARNING(("Color Index %d (%d) != vind (%d)!\n",
                                i, pcinds[i], pinds[i]));
                    }
                    
                    // !!! Indices ignored for now, assumed to be the same
                    // as for positions
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Color4f c;
                        c.setValuesRGBA(pcols[0].vec[0], pcols[0].vec[1],
                                        pcols[0].vec[2], pcols[0].vec[3]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            ocols->getField().push_back(c);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Color4f c;
                            c.setValuesRGBA(pcols[ind].vec[0], 
                                            pcols[ind].vec[1],
                                            pcols[ind].vec[2], 
                                            pcols[ind].vec[3]);
                            ocols->getField().push_back(c);
                        }
                    }
                }
                else
                {
                    FINFO(("C "));
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Color4f c;
                        c.setValuesRGBA(pcols[0].vec[0], pcols[0].vec[1],
                                        pcols[0].vec[2], pcols[0].vec[3]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            ocols->getField().push_back(c);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Color4f c;
                            c.setValuesRGBA(pcols[ind].vec[0], 
                                            pcols[ind].vec[1],
                                            pcols[ind].vec[2], 
                                            pcols[ind].vec[3]);
                            ocols->getField().push_back(c);
                        }
                    }
                }
            }    
            endEditCP(ocols);

            ogeo->setColors(ocols);
        }
    }
    
   
    // Texture coordinates
    if((bind = gset->getAttrBind(PFGS_TEXCOORD2)) != PFGS_OFF)
    {
        if(bind == PFGS_PER_PRIM)
        {
            FNOTICE(("PerformerLoader::traverseGSet: found PER_PRIM binding "
                     "for texcoords, ignoring them.\n"));
        }
        else if(bind == PFGS_OVERALL)
        {
            FINFO(("TO "));
            GeoTexCoords2fPtr otexc = GeoTexCoords2f::create();

            beginEditCP(otexc);
            pfVec2 *ptexcs;
            gset->getAttrLists(PFGS_TEXCOORD2, (void**)&ptexcs, &pinds);

            if(ptexcs)
            {
                Vec2f tc;
                tc.setValues(ptexcs[0].vec[0], ptexcs[0].vec[1]);
#if 0 // This assumes a single texcal is used as overall. Not true for 1.x
                otexc->getField().push_back(tc);
#else
                for(int i = 0; i < vertcount; ++i)
                    otexc->getField().push_back(tc);
#endif            
            }

            endEditCP(otexc);

            ogeo->setTexCoords(otexc);
        }
        else
        {
            GeoTexCoords2fPtr otexc = GeoTexCoords2f::create();

            beginEditCP(otexc);

            pfVec2 *ptexcs;
            ushort *ptexinds;
             
            gset->getAttrLists(PFGS_TEXCOORD2, (void**)&ptexcs, &ptexinds);
            
            if(ptexcs)
            {
                if(ptexinds)
                {
                    int pcmin, pcmax;
                    gset->getAttrRange(PFGS_TEXCOORD2, &pcmin, &pcmax);
            
                    FINFO(("TI %d-%d ", pcmin, pcmax));

                    // Check indices
                    if(pcmax != pmax)   
                        FWARNING(("TexCoord pmax %d != pmax %d!\n", 
                                    pcmax, pmax));
                                    
                    for(int i = 0; i < pcmax; ++i)
                    {
                        if(pinds[i] != ptexinds[i])
                            FWARNING(("TexCoord Index %d (%d) != vind (%d)!\n",
                                i, ptexinds[i], pinds[i]));
                    }
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Vec2f tc;
                        tc.setValues(ptexcs[0].vec[0], ptexcs[0].vec[1]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            otexc->getField().push_back(tc);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Vec2f tc;
                            tc.setValues(ptexcs[ind].vec[0], 
                                         ptexcs[ind].vec[1]);
                            otexc->getField().push_back(tc);
                        }
                    }
                }
                else
                {
                    FINFO(("T "));
                    
                    int ind = 0;
                    for(int j = 0; j < primcount; ++j)
                    {
                        Vec2f tc;
                        tc.setValues(ptexcs[0].vec[0], ptexcs[0].vec[1]);
                        for(UInt32 i = 0; i < cn_buffer; ++i)
                        {
                            otexc->getField().push_back(tc);
                        }

                        for(UInt32 i = 0; i < lenlist[j] - cn_buffer; 
                            ++i, ++ind)
                        {
                            Vec2f tc;
                            tc.setValues(ptexcs[ind].vec[0], 
                                         ptexcs[ind].vec[1]);
                            otexc->getField().push_back(tc);
                        }
                    }
                }
            }    
            endEditCP(otexc);

            ogeo->setTexCoords(otexc);
        }
    }


    FINFO(("\n"));

    endEditCP(ogeo);
   
//FINFO(("PerformerLoader::Geo dump %p\n", gset));
//ogeo->dump();
     
    return ogeo;
}
Exemple #6
0
NodePtr createRose()
{
    GeometryPtr geoPtr = Geometry::create();
    beginEditCP(geoPtr);
    {
        GeoPTypesUI8Ptr typesPtr = GeoPTypesUI8::create();
        typesPtr->push_back(GL_QUADS);
        geoPtr->setTypes(typesPtr);

        GeoPLengthsUI32Ptr lensPtr = GeoPLengthsUI32::create();
        lensPtr->push_back(96);
        geoPtr->setLengths(lensPtr);

        GeoPositions3fPtr posPtr = GeoPositions3f::create();

        // top
        posPtr->push_back(Vec3f( 0.00f,  1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f,  0.10f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.10f,  0.00f));

        posPtr->push_back(Vec3f( 0.00f,  1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.10f,  0.00f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f, -0.10f));

        posPtr->push_back(Vec3f( 0.00f,  1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f, -0.10f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.10f,  0.00f));

        posPtr->push_back(Vec3f( 0.00f,  1.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.10f,  0.00f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f,  0.10f));

        // bottom
        posPtr->push_back(Vec3f( 0.00f, -1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f, -0.10f,  0.00f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f,  0.10f));

        posPtr->push_back(Vec3f( 0.00f, -1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f,  0.10f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f(-0.10f, -0.10f,  0.00f));

        posPtr->push_back(Vec3f( 0.00f, -1.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f, -0.10f,  0.00f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f, -0.10f));

        posPtr->push_back(Vec3f( 0.00f, -1.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f, -0.10f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.10f, -0.10f,  0.00f));

        // left
        posPtr->push_back(Vec3f(-1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f, -0.10f,  0.00f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f,  0.10f));

        posPtr->push_back(Vec3f(-1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f,  0.10f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.10f,  0.00f));

        posPtr->push_back(Vec3f(-1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.10f,  0.00f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f, -0.10f));

        posPtr->push_back(Vec3f(-1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f, -0.10f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f(-0.10f, -0.10f,  0.00f));

        // right
        posPtr->push_back(Vec3f( 1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f,  0.10f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.10f, -0.10f,  0.00f));

        posPtr->push_back(Vec3f( 1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f, -0.10f,  0.00f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f, -0.10f));

        posPtr->push_back(Vec3f( 1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f, -0.10f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.10f,  0.00f));

        posPtr->push_back(Vec3f( 1.00f,  0.00f,  0.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.10f,  0.00f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f,  0.10f));

        // front
        posPtr->push_back(Vec3f( 0.00f,  0.00f,  1.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f,  0.10f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f,  0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f,  1.00f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f,  0.10f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f,  0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f,  0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f,  1.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f,  0.10f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f,  0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f,  1.00f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f,  0.10f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f,  0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f,  0.10f));

        // back
        posPtr->push_back(Vec3f( 0.00f,  0.00f, -1.00f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f, -0.10f));
        posPtr->push_back(Vec3f(-0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f, -0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f, -1.00f));
        posPtr->push_back(Vec3f( 0.00f,  0.10f, -0.10f));
        posPtr->push_back(Vec3f( 0.05f,  0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f, -0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f, -1.00f));
        posPtr->push_back(Vec3f( 0.10f,  0.00f, -0.10f));
        posPtr->push_back(Vec3f( 0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f, -0.10f));

        posPtr->push_back(Vec3f( 0.00f,  0.00f, -1.00f));
        posPtr->push_back(Vec3f( 0.00f, -0.10f, -0.10f));
        posPtr->push_back(Vec3f(-0.05f, -0.05f, -0.05f));
        posPtr->push_back(Vec3f(-0.10f,  0.00f, -0.10f));

        geoPtr->setPositions(posPtr);

        SimpleMaterialPtr matPtr = SimpleMaterial::create();
        beginEditCP(matPtr);
        {
            matPtr->setDiffuse(Color3f(1, 0, 0));
        }
        endEditCP(matPtr);
        geoPtr->setMaterial(matPtr);
    }
    endEditCP(geoPtr);

    calcFaceNormals(geoPtr);

    NodePtr nodePtr = Node::create();
    beginEditCP(nodePtr, Node::CoreFieldMask);
    {
        nodePtr->setCore(geoPtr);
    }
    endEditCP(nodePtr, Node::CoreFieldMask);

    return nodePtr;
}