Files
OpenSceneGraph/src/osgPlugins/gles/OpenGLESGeometryOptimizer
Marc Helbling 7cd7618e8c Updates gles from sketchfab
* fixes bbox issue for animated scenes
* fixes geometry split (perf + line/point primitive management)
* removes degenerated faces
2017-01-20 15:15:31 +01:00

250 lines
7.3 KiB
C++

/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab
*
* This application is open source and may be redistributed and/or modified
* freely and without restriction, both in commercial and non commercial
* applications, as long as this copyright notice is maintained.
*
* This application 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.
*
*/
#ifndef OPENGLES_GEOMETRY_OPTIMIZER
#define OPENGLES_GEOMETRY_OPTIMIZER
#include <osg/Node>
#include <algorithm> //std::max
//animation:
#include "AABBonBoneVisitor"
#include "AnimationCleanerVisitor"
#include "DisableAnimationVisitor"
#include "LimitMorphTargetCount"
#include "MostInfluencedGeometryByBone"
#include "RigAnimationVisitor"
#include "RigAttributesVisitor"
// geometry:
#include "BindPerVertexVisitor"
#include "DetachPrimitiveVisitor"
#include "DrawArrayVisitor"
#include "IndexMeshVisitor"
#include "PreTransformVisitor"
#include "RemapGeometryVisitor"
#include "SmoothNormalVisitor"
#include "TangentSpaceVisitor"
#include "TriangleStripVisitor"
#include "UnIndexMeshVisitor"
#include "WireframeVisitor"
#include "GeometryIndexSplitter"
#include "GeometryCleaner"
// debug
#include "GeometryInspector"
class OpenGLESGeometryOptimizer
{
public:
OpenGLESGeometryOptimizer() :
_mode("all"),
_useDrawArray(false),
_disableTriStrip(false),
_disableMergeTriStrip(false),
_disablePreTransform(false),
_disableAnimation(false),
_disableAnimationCleaning(false),
_enableAABBonBone(false),
_triStripCacheSize(16),
_triStripMinSize(2),
_generateTangentSpace(false),
_tangentUnit(0),
_maxIndexValue(65535),
_wireframe(""),
_maxMorphTarget(0),
_exportNonGeometryDrawables(false)
{}
// run the optimizer
osg::Node* optimize(osg::Node& node);
// handle options
void setMode(const std::string& mode) { _mode = mode; }
void setUseDrawArray(bool s) { _useDrawArray = s; }
void setDisableTriStrip(bool s) { _disableTriStrip = s; }
void setDisableMergeTriStrip(bool s) { _disableMergeTriStrip = s; }
void setDisablePreTransform(bool s) { _disablePreTransform = s; }
void setDisableAnimation(bool s) { _disableAnimation = s; }
void setDisableAnimationCleaning(bool s) { _disableAnimationCleaning = s; }
void setEnableAABBonBone(bool s) { _enableAABBonBone = s; }
void setTripStripCacheSize(unsigned int size) { _triStripCacheSize = size; }
void setTripStripMinSize(unsigned int size) { _triStripMinSize = std::max<unsigned int>(size, 2); }
void setExportNonGeometryDrawables(bool value) { _exportNonGeometryDrawables = value; }
void setTexCoordChannelForTangentSpace(int uv) {
_tangentUnit = uv;
_generateTangentSpace = true;
}
void setMaxIndexValue(unsigned int s) { _maxIndexValue = s; }
void setWireframe(const std::string& s) {
_wireframe = s;
if(_wireframe == std::string("outline")) {
// no use to build strip if we only want wireframe
setDisableTriStrip(true);
}
}
void setMaxMorphTarget(unsigned int maxMorphTarget) {
_maxMorphTarget = maxMorphTarget;
}
protected:
void makeAnimation(osg::Node* node) {
makeRigAnimation(node);
if(_disableAnimation) {
makeDisableAnimation(node);
}
else {
if(!_disableAnimationCleaning) {
makeCleanAnimation(node);
}
makeLimitMorphTargetCount(node);
makeAABBonBone(node, _enableAABBonBone);
makeMostInfluencedGeometryByBone(node);
}
}
void makeDisableAnimation(osg::Node* node) {
DisableAnimationVisitor disabler;
node->accept(disabler);
}
void makeCleanAnimation(osg::Node* node) {
AnimationCleanerVisitor cleaner;
node->accept(cleaner);
cleaner.clean();
}
void makeRigAnimation(osg::Node* node) {
RigAnimationVisitor anim;
node->accept(anim);
}
void makeAABBonBone(osg::Node* node, bool enableAABBonBone) {
FindSkeletons fs;
node->accept(fs);
for(unsigned int i = 0; i < fs._skls.size(); i++) {
osgAnimation::Skeleton * skl = fs._skls[i];
ComputeAABBOnBoneVisitor cabv(enableAABBonBone);
skl->accept(cabv);
cabv.computeBoundingBoxOnBones();
}
}
void makeMostInfluencedGeometryByBone(osg::Node *node) {
CollectBonesAndRigGeometriesVisitor collector;
node->accept(collector);
ComputeMostInfluencedGeometryByBone computor(collector.getRigGeometrySet(), collector.getBoneSet());
computor.compute();
}
void makeLimitMorphTargetCount(osg::Node* node) {
LimitMorphTargetCount limit(_maxMorphTarget);
node->accept(limit);
}
void makeWireframe(osg::Node* node) {
WireframeVisitor wireframe(_wireframe == std::string("inline"));
node->accept(wireframe);
}
void makeBindPerVertex(osg::Node* node) {
BindPerVertexVisitor bindpervertex;
node->accept(bindpervertex);
}
void makeIndexMesh(osg::Node* node) {
IndexMeshVisitor indexer;
node->accept(indexer);
}
void makeCleanGeometry(osg::Node* node) {
GeometryCleaner cleaner;
RemapGeometryVisitor remapper(cleaner, _exportNonGeometryDrawables);
node->accept(remapper);
}
void makeSmoothNormal(osg::Node* node) {
SmoothNormalVisitor smoother(osg::PI / 4.f, true);
node->accept(smoother);
}
void makeTangentSpace(osg::Node* node) {
TangentSpaceVisitor tangent(_tangentUnit);
node->accept(tangent);
}
void makeSplit(osg::Node* node) {
GeometryIndexSplitter splitter(_maxIndexValue);
RemapGeometryVisitor remapper(splitter, _exportNonGeometryDrawables);
node->accept(remapper);
}
void makeTriStrip(osg::Node* node) {
TriangleStripVisitor strip(_triStripCacheSize, _triStripMinSize, !_disableMergeTriStrip);
node->accept(strip);
}
void makeDrawArray(osg::Node* node) {
DrawArrayVisitor drawarray;
node->accept(drawarray);
}
void makePreTransform(osg::Node* node) {
PreTransformVisitor preTransform;
node->accept(preTransform);
}
void makeDetach(osg::Node* node) {
DetachPrimitiveVisitor detacher("wireframe", false, _wireframe == std::string("inline"));
node->accept(detacher);
}
void makeBonesAndWeightOnRigGeometry(osg::Node* node) {
RigAttributesVisitor rigger;
node->accept(rigger);
}
void makeInspectGeometry(osg::Node* node) {
GeometryInspector inspector;
node->accept(inspector);
}
std::string _mode;
bool _useDrawArray;
bool _disableTriStrip;
bool _disableMergeTriStrip;
bool _disablePreTransform;
bool _disableAnimation;
bool _disableAnimationCleaning;
bool _enableAABBonBone;
unsigned int _triStripCacheSize;
unsigned int _triStripMinSize;
bool _generateTangentSpace;
int _tangentUnit;
unsigned int _maxIndexValue;
std::string _wireframe;
unsigned int _maxMorphTarget;
bool _exportNonGeometryDrawables;
};
#endif