-/**
- * SSG callback for an in-range leaf of randomly-placed objects.
- *
- * This pretraversal callback is attached to a branch that is
- * traversed only when a leaf is in range. If the leaf is not
- * currently prepared to be populated with randomly-placed objects,
- * this callback will prepare it (actual population is handled by
- * the tri_in_range_callback for individual triangles).
- *
- * @param entity The entity to which the callback is attached (not used).
- * @param mask The entity's traversal mask (not used).
- * @return Always 1, to allow traversal and culling to continue.
- */
-// static int
-// leaf_in_range_callback (ssgEntity * entity, int mask)
-// {
-// SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
-
-// if (!data->is_filled_in) {
-// // Iterate through all the triangles
-// // and populate them.
-// int num_tris = data->leaf->getNumTriangles();
-// for ( int i = 0; i < num_tris; ++i ) {
-// data->setup_triangle(i);
-// }
-// data->is_filled_in = true;
-// }
-// return 1;
-// }
-
-
-/**
- * SSG callback for an out-of-range leaf of randomly-placed objects.
- *
- * This pretraversal callback is attached to a branch that is
- * traversed only when a leaf is out of range. If the leaf is
- * currently prepared to be populated with randomly-placed objects (or
- * is actually populated), the objects will be removed.
- *
- * @param entity The entity to which the callback is attached (not used).
- * @param mask The entity's traversal mask (not used).
- * @return Always 0, to prevent any further traversal or culling.
- */
-// static int
-// leaf_out_of_range_callback (ssgEntity * entity, int mask)
-// {
-// SGLeafUserData * data = (SGLeafUserData *)entity->getUserData();
-// if (data->is_filled_in) {
-// data->branch->removeAllKids();
-// data->is_filled_in = false;
-// }
-// return 0;
-// }
-
-
-/**
- * Randomly place objects on a surface.
- *
- * The leaf node provides the geometry of the surface, while the
- * material provides the objects and placement density. Latitude
- * and longitude are required so that the objects can be rotated
- * to the world-up vector. This function does not actually add
- * any objects; instead, it attaches an ssgRangeSelector to the
- * branch with callbacks to generate the objects when needed.
- *
- * @param leaf The surface where the objects should be placed.
- * @param branch The branch that will hold the randomly-placed objects.
- * @param center The center of the leaf in FlightGear coordinates.
- * @param material_name The name of the surface's material.
- */
-static void
-gen_random_surface_objects (osg::Node *leaf,
- osg::Group *branch,
- Point3D *center,
- SGMaterial *mat )
-{
- // OSGFIXME
-#if 0
- // If the surface has no triangles, return
- // now.
- int num_tris = leaf->getNumTriangles();
- if (num_tris < 1)
- return;
-
- // If the material has no randomly-placed
- // objects, return now.
- if (mat->get_object_group_count() < 1)
- return;
-
- // Calculate the geodetic centre of
- // the tile, for aligning automatic
- // objects.
- double xyz[3], lon_rad, lat_rad, alt_m;
- xyz[0] = center->x(); xyz[1] = center->y(); xyz[2] = center->z();
- sgCartToGeod(xyz, &lat_rad, &lon_rad, &alt_m);
-
- // LOD for the leaf
- // max random object range: 20000m
- osg::LOD * lod = new osg::LOD;
- branch->addChild(lod);
-
- // Create the in-range and out-of-range
- // branches.
- osg::Group * in_range = new osg::Group;
-// osg::Group * out_of_range = new osg::Group;
- lod->addChild(in_range, 0, 20000 /*OSGFIXME hardcoded visibility ???*/);
-// lod->addChild(out_of_range, 20000, 1e30);
-
- SGLeafUserData * data = new SGLeafUserData;
- data->is_filled_in = false;
- data->leaf = leaf;
- data->mat = mat;
- data->branch = in_range;
- data->sin_lat = sin(lat_rad);
- data->cos_lat = cos(lat_rad);
- data->sin_lon = sin(lon_rad);
- data->cos_lon = cos(lon_rad);
-
- in_range->setUserData(data);
- // OSGFIXME: implement random objects to be loaded when in sight
-// in_range->setTravCallback(SSG_CALLBACK_PRETRAV, leaf_in_range_callback);
-
- // OSGFIXME: implement deletion of tiles that are no longer used
-// out_of_range->setUserData(data);
-// out_of_range->setTravCallback(SSG_CALLBACK_PRETRAV,
-// leaf_out_of_range_callback);
-// out_of_range
-// ->addChild(new SGDummyBSphereEntity(leaf->getBSphere()->getRadius()));
+ osg::Geode* geode = new osg::Geode;
+ SGMaterialTriangleMap::const_iterator i;
+ for (i = materialTriangleMap.begin(); i != materialTriangleMap.end(); ++i) {
+ // CHUNCKED (sic) here splits up unconnected triangles parts of
+ // the mesh into different Geometry sets, presumably for better
+ // culling. I (timoore) believe it is more performant to build
+ // the biggest indexed sets possible at the expense of tight
+ // culling.
+//#define CHUNCKED
+#ifdef CHUNCKED
+ SGMaterial *mat = matlib->find(i->first);
+
+ std::list<SGTexturedTriangleBin::TriangleVector> connectSets;
+ i->second.getConnectedSets(connectSets);
+
+ std::list<SGTexturedTriangleBin::TriangleVector>::iterator j;
+ for (j = connectSets.begin(); j != connectSets.end(); ++j) {
+ osg::Geometry* geometry = i->second.buildGeometry(*j);
+ if (mat)
+ geometry->setStateSet(mat->get_state());
+ geode->addDrawable(geometry);
+ }
+#else
+ osg::Geometry* geometry = i->second.buildGeometry();
+ SGMaterial *mat = matlib->find(i->first);
+ if (mat)
+ geometry->setStateSet(mat->get_state());
+ geode->addDrawable(geometry);