- Edited
Actually, I want to implement a UI similar to Unity's, which is adding a special node Cesium3DTileset and a CesiumGeoreferece node will be add automatic to its' parent node, and it has a resouce type default value like EarthCenterEarthFixed value. But now it gets lots of warnings about default value.
header:
#pragma once
#include <CesiumGeospatial/LocalHorizontalCoordinateSystem.h>
#include <glm/mat4x4.hpp>
#include <godot_cpp/classes/node3d.hpp>
#include <godot_cpp/classes/resource.hpp>
#include <optional>
using namespace godot;
namespace CesiumForGodot
{
class CesiumGeoreference : public Node3D
{
GDCLASS( CesiumGeoreference, Node3D )
private:
Ref<Resource> originAuthority;
double scale = 1.0f;
std::optional<CesiumGeospatial::LocalHorizontalCoordinateSystem> coordinateSystem;
glm::dmat4 localToEcef = glm::dmat4( 1.0f );
glm::dmat4 ecefToLocal = glm::dmat4( 1.0f );
protected:
static void _bind_methods();
public:
CesiumGeoreference();
~CesiumGeoreference();
// void _process(double delta) override;
void set_originAuthority( const Ref<Resource> p_originAuthority );
Ref<Resource> get_originAuthority() const;
void set_scale( const double p_scale );
double get_scale() const;
CesiumGeospatial::LocalHorizontalCoordinateSystem CesiumGeoreference::
createCoordinateSystem() const;
const CesiumGeospatial::LocalHorizontalCoordinateSystem &getCoordinateSystem();
void computeLocalToEarthCenteredEarthFixedTransformation();
void updateGeoreference();
};
} // namespace CesiumForGodot
definition:
#include "CesiumGeoreference.h"
#include "CesiumOriginAuthority.h"
#include <CesiumGeospatial/LocalHorizontalCoordinateSystem.h>
#include <CesiumUtility/Math.h>
#include <godot_cpp/core/class_db.hpp>
#include <godot_cpp/variant/utility_functions.hpp>
using namespace CesiumGeospatial;
using namespace CesiumUtility;
using namespace CesiumForGodot;
void CesiumGeoreference::_bind_methods()
{
ClassDB::bind_method( D_METHOD( "get_scale" ), &CesiumGeoreference::get_scale );
ClassDB::bind_method( D_METHOD( "set_scale", "p_scale" ), &CesiumGeoreference::set_scale );
ClassDB::add_property( "CesiumGeoreference", PropertyInfo( Variant::FLOAT, "scale" ),
"set_scale", "get_scale" );
ClassDB::bind_method( D_METHOD( "get_originAuthority" ),
&CesiumGeoreference::get_originAuthority );
ClassDB::bind_method( D_METHOD( "set_originAuthority", "p_originAuthority" ),
&CesiumGeoreference::set_originAuthority );
ClassDB::add_property( "CesiumGeoreference",
PropertyInfo( Variant::OBJECT, "originAuthority",
PROPERTY_HINT_RESOURCE_TYPE,
"LongitudeLatitudeHeight, EarthCenteredEarthFixed" ),
"set_originAuthority", "get_originAuthority" );
ClassDB::bind_method( D_METHOD( "updateGeoreference" ),
&CesiumGeoreference::updateGeoreference );
ADD_SIGNAL( MethodInfo( "scale_changed", PropertyInfo( Variant::OBJECT, "node" ),
PropertyInfo( Variant::FLOAT, "scale" ) ) );
}
CesiumGeoreference::CesiumGeoreference()
{
Ref<EarthCenteredEarthFixed> originAuthority;
originAuthority.instantiate();
this->set_originAuthority( originAuthority );
this->scale = 1.0;
}
CesiumGeoreference::~CesiumGeoreference()
{
// Add your cleanup here.
}
void CesiumGeoreference::set_originAuthority( const Ref<Resource> p_originAuthority )
{
if ( originAuthority != p_originAuthority )
{
if ( originAuthority != nullptr )
{
String type_name = originAuthority->get_name();
if ( type_name == "LongitudeLatitudeHeight" )
{
originAuthority->disconnect( "lngLatH_changed",
Callable( this, "updateGeoreference" ) );
}
else
{
originAuthority->disconnect( "ecef_changed",
Callable( this, "updateGeoreference" ) );
}
}
originAuthority = p_originAuthority;
if ( originAuthority != nullptr )
{
String type_name = originAuthority->get_name();
if ( type_name == "LongitudeLatitudeHeight" )
{
p_originAuthority->connect( "lngLatH_changed",
Callable( this, "updateGeoreference" ) );
}
else
{
p_originAuthority->connect( "ecef_changed",
Callable( this, "updateGeoreference" ) );
}
}
}
}
Ref<Resource> CesiumGeoreference::get_originAuthority() const
{
return originAuthority;
}
void CesiumGeoreference::set_scale( const double p_scale )
{
if ( scale != p_scale )
{
scale = p_scale;
emit_signal( "scale_changed" );
this->updateGeoreference();
}
}
double CesiumGeoreference::get_scale() const
{
return scale;
}
LocalHorizontalCoordinateSystem CesiumGeoreference::createCoordinateSystem() const
{
if ( originAuthority.is_valid() )
{
String type_name = originAuthority->get_name();
if ( type_name == "LongitudeLatitudeHeight" )
{
Ref<CesiumForGodot::LongitudeLatitudeHeight> lngLatH =
Ref<LongitudeLatitudeHeight>( originAuthority.ptr() );
return LocalHorizontalCoordinateSystem(
Cartographic::fromDegrees( lngLatH->get_longitude(), lngLatH->get_latitude(),
lngLatH->get_height() ),
LocalDirection::East, LocalDirection::Up, LocalDirection::North, 1.0 / scale );
}
else
{
Ref<CesiumForGodot::EarthCenteredEarthFixed> p_ecef =
Ref<EarthCenteredEarthFixed>( originAuthority.ptr() );
return LocalHorizontalCoordinateSystem(
glm::dvec3( p_ecef->get_ecefX(), p_ecef->get_ecefY(), p_ecef->get_ecefZ() ),
LocalDirection::East, LocalDirection::Up, LocalDirection::North, 1.0 / scale );
}
}
}
const CesiumGeospatial::LocalHorizontalCoordinateSystem &CesiumGeoreference::getCoordinateSystem()
{
if ( !coordinateSystem )
{
this->computeLocalToEarthCenteredEarthFixedTransformation();
}
return *coordinateSystem;
}
void CesiumGeoreference::computeLocalToEarthCenteredEarthFixedTransformation()
{
this->coordinateSystem = this->createCoordinateSystem();
this->localToEcef = this->coordinateSystem->getLocalToEcefTransformation();
this->ecefToLocal = this->coordinateSystem->getEcefToLocalTransformation();
}
void CesiumGeoreference::updateGeoreference()
{
UtilityFunctions::print( "---updateGeoreference-----" );
this->computeLocalToEarthCenteredEarthFixedTransformation();
}