+Geometry* makeSharedTreeGeometry(int numQuads)
+{
+ // generate a repeatable random seed
+ mt seed;
+ mt_init(&seed, unsigned(123));
+ // set up the coords
+ osg::Vec3Array* v = new osg::Vec3Array;
+ osg::Vec2Array* t = new osg::Vec2Array;
+ v->reserve(numQuads * 4);
+ t->reserve(numQuads * 4);
+ for (int i = 0; i < numQuads; ++i) {
+ // Apply a random scaling factor and texture index.
+ float h = (mt_rand(&seed) + mt_rand(&seed)) / 2.0f + 0.5f;
+ float cw = h * .5;
+ v->push_back(Vec3(0.0f, -cw, 0.0f));
+ v->push_back(Vec3(0.0f, cw, 0.0f));
+ v->push_back(Vec3(0.0f, cw, h));
+ v->push_back(Vec3(0.0f,-cw, h));
+ // The texture coordinate range is not the entire coordinate
+ // space, as the texture has a number of different trees on
+ // it. Here we assign random coordinates and let the shader
+ // choose the variety.
+ float variety = mt_rand(&seed);
+ t->push_back(Vec2(variety, 0.0f));
+ t->push_back(Vec2(variety + 1.0f, 0.0f));
+ t->push_back(Vec2(variety + 1.0f, 1.0f));
+ t->push_back(Vec2(variety, 1.0f));
+ }
+ Geometry* result = new Geometry;
+ result->setVertexArray(v);
+ result->setTexCoordArray(0, t);
+ result->setComputeBoundingBoxCallback(new TreesBoundingBoxCallback);
+ result->setUseDisplayList(false);
+ return result;
+}