- sgVec3 center;
- calc_center_point( nodes, pnt_i, center );
- // cout << center[0] << "," << center[1] << "," << center[2] << endl;
-
-
- // find a vector perpendicular to the normal.
- sgVec3 perp1;
- if ( !vertical ) {
- // normal isn't vertical so we can use up as our first vector
- sgNormalizeVec3( perp1, up );
- } else {
- // normal is vertical so we have to work a bit harder to
- // determine our first vector
- sgVec3 pt1, pt2;
- sgSetVec3( pt1, nodes[pnt_i[0]][0], nodes[pnt_i[0]][1],
- nodes[pnt_i[0]][2] );
- sgSetVec3( pt2, nodes[pnt_i[1]][0], nodes[pnt_i[1]][1],
- nodes[pnt_i[1]][2] );
-
- sgSubVec3( perp1, pt2, pt1 );
- sgNormalizeVec3( perp1 );
- }
-
- ssgVertexArray *vl = new ssgVertexArray( 3 * pnt_i.size() );
- ssgNormalArray *nl = new ssgNormalArray( 3 * pnt_i.size() );
- ssgColourArray *cl = new ssgColourArray( 3 * pnt_i.size() );
-
- unsigned int i;
- sgVec3 pt, normal;
- for ( i = 0; i < pnt_i.size(); ++i ) {
- sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
- nodes[pnt_i[i]][2] );
- sgSubVec3( pt, center );
- sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
- normals[nml_i[i]][2] );
-
- // calculate a vector perpendicular to dir and up
- sgVec3 perp2;
- sgVectorProductVec3( perp2, normal, perp1 );
-
- // front face
- sgVec3 tmp3;
- sgCopyVec3( tmp3, pt );
- vl->add( tmp3 );
- sgAddVec3( tmp3, perp1 );
- vl->add( tmp3 );
- sgAddVec3( tmp3, perp2 );
- vl->add( tmp3 );
- // sgSubVec3( tmp3, perp1 );
- // vl->add( tmp3 );
-
- nl->add( normal );
- nl->add( normal );
- nl->add( normal );
- // nl->add( normal );
-
- sgVec4 color;
- sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
- cl->add( color );
- sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
- cl->add( color );
- cl->add( color );
- // cl->add( color );
- }
-
- ssgLeaf *leaf =
- new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
-
- if ( mat != NULL ) {
- leaf->setState( mat->get_state() );
- } else {
- SG_LOG( SG_TERRAIN, SG_ALERT, "Warning: material = NULL" );
- }
-
- // put an LOD on each lighting component
- ssgRangeSelector *lod = new ssgRangeSelector;
- lod->setRange( 0, SG_ZERO );
- lod->setRange( 1, 20000 );
- lod->addKid( leaf );
-
- // create the transformation.
- sgCoord coord;
- sgSetCoord( &coord, center[0], center[1], center[2], 0.0, 0.0, 0.0 );
- ssgTransform *trans = new ssgTransform;
- trans->setTransform( &coord );
- trans->addKid( lod );
-
- return trans;
+ osg::Vec3Array* vertices = new osg::Vec3Array;
+ osg::Vec4Array* colors = new osg::Vec4Array;
+
+ SGVec4f visibleColor(light.color);
+ SGVec4f invisibleColor(visibleColor[0], visibleColor[1],
+ visibleColor[2], 0);
+ SGVec3f normal = normalize(light.normal);
+ SGVec3f perp1 = perpendicular(normal);
+ SGVec3f perp2 = cross(normal, perp1);
+ SGVec3f position = light.position;
+ vertices->push_back(position.osg());
+ vertices->push_back((position + perp1).osg());
+ vertices->push_back((position + perp2).osg());
+ colors->push_back(visibleColor.osg());
+ colors->push_back(invisibleColor.osg());
+ colors->push_back(invisibleColor.osg());
+
+ osg::Geometry* geometry = new osg::Geometry;
+ geometry->setVertexArray(vertices);
+ geometry->setNormalBinding(osg::Geometry::BIND_OFF);
+ geometry->setColorArray(colors);
+ geometry->setColorBinding(osg::Geometry::BIND_PER_VERTEX);
+ // Enlarge the bounding box to avoid such light nodes being victim to
+ // small feature culling.
+ geometry->setComputeBoundingBoxCallback(new SGEnlargeBoundingBox(1));
+
+ osg::DrawArrays* drawArrays;
+ drawArrays = new osg::DrawArrays(osg::PrimitiveSet::TRIANGLES,
+ 0, vertices->size());
+ geometry->addPrimitiveSet(drawArrays);
+
+ osg::StateSet* stateSet = geometry->getOrCreateStateSet();
+ stateSet->setRenderBinDetails(POINT_LIGHTS_BIN, "DepthSortedBin");
+
+ osg::Material* material = new osg::Material;
+ material->setColorMode(osg::Material::OFF);
+ stateSet->setAttribute(material);
+
+ osg::CullFace* cullFace = new osg::CullFace;
+ cullFace->setMode(osg::CullFace::BACK);
+ stateSet->setAttribute(cullFace, osg::StateAttribute::ON);
+ stateSet->setMode(GL_CULL_FACE, osg::StateAttribute::ON);
+
+ osg::PolygonMode* polygonMode = new osg::PolygonMode;
+ polygonMode->setMode(osg::PolygonMode::FRONT, osg::PolygonMode::POINT);
+ stateSet->setAttribute(polygonMode);
+
+ stateSet->setMode(GL_LIGHTING, osg::StateAttribute::OFF);
+
+ osg::BlendFunc* blendFunc = new osg::BlendFunc;
+ stateSet->setAttribute(blendFunc);
+ stateSet->setMode(GL_BLEND, osg::StateAttribute::ON);
+
+ osg::AlphaFunc* alphaFunc;
+ alphaFunc = new osg::AlphaFunc(osg::AlphaFunc::GREATER, 0.01);
+ stateSet->setAttribute(alphaFunc);
+ stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
+
+ osg::Geode* geode = new osg::Geode;
+ geode->addDrawable(geometry);
+
+ return geode;