/* -*-c++-*- */
/* osgEarth - Dynamic map generation toolkit for OpenSceneGraph
 * Copyright 2008-2009 Pelican Ventures, Inc.
 * http://osgearth.org
 *
 * osgEarth is free software; you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program 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
 * GNU Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>
 */
#ifndef OSGEARTH_DROAM_ENGINE_GEODETIC_MANIFOLD_H
#define OSGEARTH_DROAM_ENGINE_GEODETIC_MANIFOLD_H 1

#include "Manifold"
#include "MeshManager"
#include "Diamond"
#include <osg/CoordinateSystemNode>
#include <osgEarth/Profile>

/** The top-level diamond layout for a round earth */
class GeodeticManifold : public Manifold
{
public:
    GeodeticManifold();

public:
    /** generate children up to the specified level */
    void seed( Level maxLevel );

    /** apply culling to the manifold. */
    void cull( osgUtil::CullVisitor* cv );

public: // Manifold overrides

    /** builds the base manifold mesh. */
    void initialize( MeshManager* mesh ); // override

    /** calculates the midpoint between two map coodinates */
    osg::Vec3d midpoint( const osg::Vec3d& mapCoord0, const osg::Vec3d& mapCoord1 ) const;

    /** calculates the initial bound for the manifold. */
    osg::BoundingSphere initialBound() const;

    /** creates a mesh node for a coordinate in manifold profile */
    MeshNode createNode( const osg::Vec3d& manifoldCoord ) const;

public:
    osg::BoundingSphere _bs;
    osg::ref_ptr<const Profile> _profile;
    osg::ref_ptr<const osg::EllipsoidModel> _ellipsoid;
    osg::ref_ptr<Diamond> _vd[6];  // vertex diamonds
    osg::ref_ptr<Diamond> _fd[4];  // intermediate base diamonds
    osg::ref_ptr<Diamond> _ed[8];  // first geometry diamonds

    osg::Vec3d p(double x, double y, double z);
};

#endif // OSGEARTH_DROAM_ENGINE_GEODETIC_MANIFOLD_H
