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; }
// 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; }
// 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; }
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; }