/* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2006 Robert Osfield * * This library is open source and may be redistributed and/or modified under * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or * (at your option) any later version. The full license is in LICENSE file * included with this distribution, and on the openscenegraph.org website. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * OpenSceneGraph Public License for more details. */ #include #include #include using namespace osg; /////////////////////////////////////////////////////////////////////////////////////////// // // Cluster culling callback // ClusterCullingCallback::ClusterCullingCallback(): _radius(-1.0f), _deviation(-1.0f) { } ClusterCullingCallback::ClusterCullingCallback(const ClusterCullingCallback& ccc,const CopyOp& copyop): Drawable::CullCallback(ccc,copyop), _controlPoint(ccc._controlPoint), _normal(ccc._normal), _radius(ccc._radius), _deviation(ccc._deviation) { } ClusterCullingCallback::ClusterCullingCallback(const osg::Vec3& controlPoint, const osg::Vec3& normal, float deviation): _controlPoint(controlPoint), _normal(normal), _radius(-1.0f), _deviation(deviation) { } ClusterCullingCallback::ClusterCullingCallback(const osg::Drawable* drawable) { computeFrom(drawable); } struct ComputeAveragesFunctor { ComputeAveragesFunctor(): _num(0) {} inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, bool) { // calc orientation of triangle. osg::Vec3d normal = (v2-v1)^(v3-v1); if (normal.normalize()!=0.0f) { _normal += normal; } _center += v1; _center += v2; _center += v3; ++_num; } osg::Vec3 center() { return _center / (double)(3*_num); } osg::Vec3 normal() { _normal.normalize(); return _normal; } unsigned int _num; Vec3d _center; Vec3d _normal; }; struct ComputeDeviationFunctor { ComputeDeviationFunctor(): _deviation(1.0), _radius2(0.0) {} void set(const osg::Vec3& center,const osg::Vec3& normal) { _center = center; _normal = normal; } inline void operator() ( const osg::Vec3 &v1, const osg::Vec3 &v2, const osg::Vec3 &v3, bool) { // calc orientation of triangle. osg::Vec3 normal = (v2-v1)^(v3-v1); if (normal.normalize()!=0.0f) { _deviation = osg::minimum(_normal*normal,_deviation); } _radius2 = osg::maximum((v1-_center).length2(),_radius2); _radius2 = osg::maximum((v2-_center).length2(),_radius2); _radius2 = osg::maximum((v3-_center).length2(),_radius2); } osg::Vec3 _center; osg::Vec3 _normal; float _deviation; float _radius2; }; void ClusterCullingCallback::computeFrom(const osg::Drawable* drawable) { TriangleFunctor caf; drawable->accept(caf); _controlPoint = caf.center(); _normal = caf.normal(); TriangleFunctor cdf; cdf.set(_controlPoint,_normal); drawable->accept(cdf); // osg::notify(osg::NOTICE)<<"ClusterCullingCallback::computeFrom() _controlPoint="<<_controlPoint<