/* -*-c++-*- OpenSceneGraph - Copyright (C) Sketchfab */

#include <osg/Geometry>
#include <osgAnimation/MorphGeometry>

#include "GeometryUniqueVisitor"
#include "TriangleMeshSmoother"


class SmoothNormalVisitor : public GeometryUniqueVisitor {
public:
    SmoothNormalVisitor(float creaseAngle, bool comparePosition=false):
        GeometryUniqueVisitor("SmoothNormalVisitor"),
        _creaseAngle(creaseAngle),
        _comparePosition(comparePosition)
    {}

    void process(osg::Geometry& geometry) {
        if(!geometry.getNormalArray()) {
            TriangleMeshSmoother(geometry, _creaseAngle, _comparePosition, TriangleMeshSmoother::recompute);
        }
        else {
            TriangleMeshSmoother(geometry, _creaseAngle, _comparePosition, TriangleMeshSmoother::diagnose);
        }
    }

    void process(osgAnimation::MorphGeometry& morphGeometry) {
        TriangleMeshSmoother(morphGeometry, 0, true, TriangleMeshSmoother::smooth_all);
        osgAnimation::MorphGeometry::MorphTargetList targets = morphGeometry.getMorphTargetList();
        for(osgAnimation::MorphGeometry::MorphTargetList::iterator target = targets.begin() ; target != targets.end() ; ++ target) {
            // check normal orientation using the same primitives as parent geometry
            osg::Geometry::PrimitiveSetList& primitives = target->getGeometry()->getPrimitiveSetList();
            target->getGeometry()->setPrimitiveSetList(morphGeometry.getPrimitiveSetList());

            TriangleMeshSmoother(*target->getGeometry(), 0, true, TriangleMeshSmoother::smooth_all);

            target->getGeometry()->setPrimitiveSetList(primitives);
        }
    }

protected:
    float _creaseAngle;
    bool _comparePosition;
};
