1+ #include " render_pipeline/rpcore/util/circular_points_node.hpp"
2+
3+ #include < shaderAttrib.h>
4+ #include < geomNode.h>
5+
6+ #include < spdlog/fmt/fmt.h>
7+
8+ #include " render_pipeline/rpcore/render_pipeline.h"
9+ #include " render_pipeline/rpcore/util/primitives.hpp"
10+
11+ namespace rpcore {
12+
13+ static_assert (std::is_standard_layout<LMatrix4f>::value, " std::is_standard_layout<LMatrix4f>::value" );
14+ static_assert (sizeof (LMatrix4f) == sizeof (float )*16 , " sizeof(LMatrix4f) == sizeof(float)*16" );
15+
16+ struct CircularPointsNode ::Impl
17+ {
18+ Impl (const std::string& name, const std::vector<LPoint3f>& positions, float radius, const std::string& effect_path,
19+ GeomEnums::UsageHint buffer_hint);
20+
21+ void set_position (const LPoint3f& position, int point_index);
22+ void set_positions (const std::vector<LPoint3f>& positions);
23+
24+ void set_radius (float radius);
25+
26+ void upload_positions (void );
27+
28+ bool dirty_ = true ;
29+ NodePath points_np_;
30+ std::vector<LPoint3f> positions_;
31+ };
32+
33+ CircularPointsNode::Impl::Impl (const std::string& name, const std::vector<LPoint3f>& positions, float radius,
34+ const std::string& effect_path, GeomEnums::UsageHint buffer_hint)
35+ {
36+ points_np_ = create_points (name, positions, radius);
37+ positions_ = positions;
38+
39+ // Load the effect
40+ std::string epath = effect_path;
41+ if (epath.empty ())
42+ epath = " effects/circular_points.yaml" ;
43+
44+ rpcore::RenderPipeline::get_global_ptr ()->set_effect (points_np_, epath);
45+
46+ set_radius (radius);
47+ points_np_.set_attrib (DCAST (ShaderAttrib, points_np_.get_attrib (ShaderAttrib::get_class_type ()))->set_flag (ShaderAttrib::F_shader_point_size, true ));
48+ }
49+
50+ void CircularPointsNode::Impl::set_position (const LPoint3f& position, int point_index)
51+ {
52+ dirty_ = true ;
53+ positions_[point_index] = position;
54+ }
55+
56+ void CircularPointsNode::Impl::set_positions (const std::vector<LPoint3f>& positions)
57+ {
58+ if (positions.size () == positions_.size ())
59+ {
60+ dirty_ = true ;
61+ positions_ = positions;
62+ }
63+ else
64+ {
65+ RPObject::global_error (" CircularPointsNode" ,
66+ fmt::format (" The size of positions ({}) is NOT same as current size ({})." , positions.size (), positions_.size ()));
67+ }
68+ }
69+
70+ void CircularPointsNode::Impl::set_radius (float radius)
71+ {
72+ points_np_.set_shader_input (" point_radius" , radius);
73+ }
74+
75+ void CircularPointsNode::Impl::upload_positions (void )
76+ {
77+ if (!dirty_)
78+ return ;
79+
80+ PT (GeomVertexArrayData) vertex_array = DCAST (GeomNode, points_np_.node ())->modify_geom (0 )->modify_vertex_data ()->modify_array (0 );
81+
82+ vertex_array->modify_handle ()->copy_data_from (
83+ reinterpret_cast <const unsigned char *>(positions_.data ()),
84+ positions_.size () * sizeof (decltype (positions_)::value_type));
85+
86+ dirty_ = false ;
87+ }
88+
89+ // ************************************************************************************************
90+ CircularPointsNode::CircularPointsNode (const std::string& name, const std::vector<LPoint3f>& positions, float radius,
91+ const std::string& effect_path, GeomEnums::UsageHint buffer_hint): impl_(std::make_unique<Impl>(name, positions,
92+ radius, effect_path, buffer_hint))
93+ {
94+ }
95+
96+ CircularPointsNode::~CircularPointsNode (void ) = default ;
97+
98+ NodePath CircularPointsNode::get_nodepath (void ) const
99+ {
100+ return impl_->points_np_ ;
101+ }
102+
103+ int CircularPointsNode::get_point_count (void ) const
104+ {
105+ return static_cast <int >(impl_->positions_ .size ());
106+ }
107+
108+ const LPoint3f& CircularPointsNode::get_position (int point_index) const
109+ {
110+ return impl_->positions_ [point_index];
111+ }
112+
113+ const std::vector<LPoint3f>& CircularPointsNode::get_positions (void ) const
114+ {
115+ return impl_->positions_ ;
116+ }
117+
118+ LPoint3f* CircularPointsNode::modify_positions (void )
119+ {
120+ impl_->dirty_ = true ;
121+ return impl_->positions_ .data ();
122+ }
123+
124+ void CircularPointsNode::set_position (const LPoint3f& position, int point_index)
125+ {
126+ if (point_index >= static_cast <int >(impl_->positions_ .size ()))
127+ {
128+ RPObject::global_error (" CircularPointsNode" , " Out of range of positions of CircularPointsNode." );
129+ return ;
130+ }
131+
132+ impl_->set_position (position, point_index);
133+ }
134+
135+ void CircularPointsNode::set_positions (const std::vector<LPoint3f>& positions)
136+ {
137+ impl_->set_positions (positions);
138+ }
139+
140+ void CircularPointsNode::upload_positions (void )
141+ {
142+ impl_->upload_positions ();
143+ }
144+
145+ void CircularPointsNode::set_radius (float radius)
146+ {
147+ impl_->set_radius (radius);
148+ }
149+
150+ }
0 commit comments