Skip to content

Commit 82f3410

Browse files
committed
Add node component for circular point
- Remove function to create circular points.
1 parent e41abf5 commit 82f3410

File tree

6 files changed

+210
-26
lines changed

6 files changed

+210
-26
lines changed

files.cmake

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ set(header_rpcore_stages
114114
)
115115

116116
set(header_rpcore_util
117+
"${PROJECT_SOURCE_DIR}/render_pipeline/rpcore/util/circular_points_node.hpp"
117118
"${PROJECT_SOURCE_DIR}/render_pipeline/rpcore/util/cubemap_filter.h"
118119
"${PROJECT_SOURCE_DIR}/render_pipeline/rpcore/util/generic.h"
119120
"${PROJECT_SOURCE_DIR}/render_pipeline/rpcore/util/instancing_node.hpp"
@@ -288,6 +289,7 @@ set(source_rpcore_stages
288289
)
289290

290291
set(source_rpcore_util
292+
"${PROJECT_SOURCE_DIR}/src/rpcore/util/circular_points_node.cpp"
291293
"${PROJECT_SOURCE_DIR}/src/rpcore/util/cubemap_filter.cpp"
292294
"${PROJECT_SOURCE_DIR}/src/rpcore/util/display_shader_builder.cpp"
293295
"${PROJECT_SOURCE_DIR}/src/rpcore/util/display_shader_builder.h"
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#pragma once
2+
3+
#include <nodePath.h>
4+
5+
#include <render_pipeline/rpcore/config.h>
6+
7+
namespace rpcore {
8+
9+
class RENDER_PIPELINE_DECL CircularPointsNode
10+
{
11+
public:
12+
CircularPointsNode(const std::string& name, const std::vector<LPoint3f>& positions, float radius=1.0f,
13+
const std::string& effect_path="", GeomEnums::UsageHint buffer_hint=GeomEnums::UH_static);
14+
15+
~CircularPointsNode(void);
16+
17+
NodePath get_nodepath(void) const;
18+
19+
/** Get the count of instances. */
20+
int get_point_count(void) const;
21+
22+
/** Get position. */
23+
const LPoint3f& get_position(int point_index) const;
24+
25+
/** Get local instancing tranforms. */
26+
const std::vector<LPoint3f>& get_positions(void) const;
27+
28+
LPoint3f* modify_positions(void);
29+
30+
/** Set local instancing transform. */
31+
void set_position(const LPoint3f& positions, int point_index);
32+
33+
/** Set local instancing transforms and change instance count to the size of @p transforms. */
34+
void set_positions(const std::vector<LPoint3f>& positions);
35+
36+
/** Upload transform buffer texture to GPU. */
37+
void upload_positions(void);
38+
39+
void set_radius(float radius);
40+
41+
private:
42+
struct Impl;
43+
std::shared_ptr<Impl> impl_;
44+
};
45+
46+
}
47+

render_pipeline/rpcore/util/primitives.hpp

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,8 @@
66

77
namespace rpcore {
88

9-
RENDER_PIPELINE_DECL NodePath create_points(const std::string& name, int count);
10-
11-
/**
12-
* Create circular points with radius.
13-
*
14-
* This creates circular points using 'effects/circular_point.yaml' effect.
15-
*/
16-
RENDER_PIPELINE_DECL NodePath create_circular_points(const std::string& name, int count, float radius);
9+
RENDER_PIPELINE_DECL NodePath create_points(const std::string& name, const std::vector<LPoint3f>& positions,
10+
float radius=1.0f, GeomEnums::UsageHint buffer_hint=Geom::UsageHint::UH_static);
1711

1812
RENDER_PIPELINE_DECL NodePath create_cube(const std::string& name);
1913
RENDER_PIPELINE_DECL NodePath create_sphere(const std::string& name, unsigned int latitude, unsigned int longitude);
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
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+
}

src/rpcore/util/instancing_node.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ void InstancingNode::remove_instance(int instance_index, bool upload)
128128
{
129129
if (instance_index >= static_cast<int>(impl_->transforms_.size()))
130130
{
131-
std::cout << "Out of range in transform of InstancingNode.";
131+
RPObject::global_error("InstancingNode", "Out of range in transform of InstancingNode.");
132132
return;
133133
}
134134

@@ -159,7 +159,7 @@ void InstancingNode::set_transform(const LMatrix4f& transform, int instance_inde
159159
{
160160
if (instance_index >= static_cast<int>(impl_->transforms_.size()))
161161
{
162-
std::cout << "Out of range in transform of InstancingNode.";
162+
RPObject::global_error("InstancingNode", "Out of range in transform of InstancingNode.");
163163
return;
164164
}
165165

src/rpcore/util/primitives.cpp

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
#include <geomPoints.h>
66
#include <geomNode.h>
77
#include <materialAttrib.h>
8-
#include <shaderAttrib.h>
98

109
#include "render_pipeline/rpcore/render_pipeline.h"
1110
#include "render_pipeline/rpcore/util/rpmaterial.hpp"
@@ -24,16 +23,18 @@ static NodePath create_geom_node(const std::string& name, Geom* geom)
2423
return np;
2524
}
2625

27-
NodePath create_points(const std::string& name, int count)
26+
NodePath create_points(const std::string& name, const std::vector<LPoint3f>& positions, float radius, GeomEnums::UsageHint buffer_hint)
2827
{
28+
const size_t count = positions.size();
29+
2930
// create vertices
30-
PT(GeomVertexData) vdata = new GeomVertexData(name, GeomVertexFormat::get_v3(), Geom::UsageHint::UH_static);
31+
PT(GeomVertexData) vdata = new GeomVertexData(name, GeomVertexFormat::get_v3(), buffer_hint);
3132
vdata->unclean_set_num_rows(count);
3233

3334
GeomVertexWriter vertex(vdata, InternalName::get_vertex());
3435

3536
for (int k = 0; k < count; ++k)
36-
vertex.add_data3f(0.0f);
37+
vertex.add_data3f(positions[k]);
3738

3839
// create indices
3940
PT(GeomPoints) prim = new GeomPoints(Geom::UsageHint::UH_static);
@@ -45,18 +46,8 @@ NodePath create_points(const std::string& name, int count)
4546
PT(Geom) geom = new Geom(vdata);
4647
geom->add_primitive(prim);
4748

48-
return create_geom_node(name, geom);
49-
}
50-
51-
NodePath create_circular_points(const std::string& name, int count, float radius)
52-
{
53-
NodePath np = create_points(name, count);
54-
55-
np.set_shader_input("point_radius", radius);
56-
57-
rpcore::RenderPipeline::get_global_ptr()->set_effect(np, "effects/circular_points.yaml");
58-
np.set_attrib(DCAST(ShaderAttrib, np.get_attrib(ShaderAttrib::get_class_type()))->set_flag(ShaderAttrib::F_shader_point_size, true));
59-
49+
NodePath np = create_geom_node(name, geom);
50+
np.set_render_mode_thickness(radius);
6051
return np;
6152
}
6253

0 commit comments

Comments
 (0)