13std::string toColor(
const gml::dvec3& c)
16 auto fn = [](
double c)
18 c = gml::clamp(c, 0.0, 1.0);
19 return static_cast<int>(255 *
c);
22 ss <<
"rgb(" << fn(c[0]) <<
"," << fn(c[1]) <<
"," << fn(c[2]) <<
")";
28svg_writer_t::BaseElem::BaseElem(
double z,
const gml::dvec3& color) : z_{
z}, color_{color}
32svg_writer_t::BaseElem::~BaseElem()
36svg_writer_t::VertexElem::VertexElem(
const gml::dvec3& p,
const gml::dvec3& color) : BaseElem{
p[2], color}, p_{
p}
40void svg_writer_t::VertexElem::stream(std::ostream& os)
const
43 <<
"cx=\"" << p_[0] <<
"\" cy=\"" << p_[1] <<
"\" "
44 <<
"r=\"3\" style=\"fill: " << toColor(color_) <<
"\" />\n";
47svg_writer_t::LineElem::LineElem(
const gml::dvec3& p1,
const gml::dvec3& p2,
const gml::dvec3& color)
48 : BaseElem{(p1[2] + p2[2]) / 2.0, color}
54void svg_writer_t::LineElem::stream(std::ostream& os)
const
57 <<
"x1=\"" << p1_[0] <<
"\" y1=\"" << p1_[1] <<
"\" "
58 <<
"x2=\"" << p2_[0] <<
"\" y2=\"" << p2_[1] <<
"\" "
59 <<
"style=\"stroke: " << toColor(color_) <<
";\" />\n";
62svg_writer_t::TriangleElem::TriangleElem(
const gml::dvec3& p1,
65 const gml::dvec3& color)
66 : BaseElem{(p1[2] + p2[2] + p3[2]) / 3.0, color}
71void svg_writer_t::TriangleElem::stream(std::ostream& os)
const
75 for(gml::dvec3 p : p_)
77 os <<
p[0] <<
"," <<
p[1] <<
" ";
80 os <<
"style=\"fill: " << toColor(color_) <<
";\" />\n";
83gml::dvec3 svg_writer_t::project(
const gml::dvec3& p)
const
85 auto temp =
gml::project(p, viewProjMatrix_, viewportOrigin_, viewportSize_);
86 temp[1] = size_[1] - temp[1];
90gml::dvec3 svg_writer_t::normalToColor(
const gml::dvec3&
normal)
const
92 double d = gml::dot(
normal, lightDir_);
93 d = gml::clamp(d, 0.0, 1.0);
99 : size_{width, height}
102 , viewProjMatrix_{1.0}
103 , viewportOrigin_{0, 0}
104 , viewportSize_{width, height}
105 , lightDir_{1.0, 2.0, 3.0}
109 lightDir_ = normalize(lightDir_);
114 viewMatrix_ = matrix;
115 viewProjMatrix_ = projMatrix_ * viewMatrix_;
120 projMatrix_ = gml::perspective(fovy, aspect, zNear, zFar);
121 viewProjMatrix_ = projMatrix_ * viewMatrix_;
127 viewProjMatrix_ = projMatrix_ * viewMatrix_;
132 viewportOrigin_ = gml::ivec2{
x,
y};
133 viewportSize_ = gml::ivec2{width, height};
143 elems_.push_back(std::unique_ptr<BaseElem>{
new VertexElem{project(p), color}});
150 elems_.push_back(std::unique_ptr<BaseElem>{
new LineElem{project(p1), project(p2), color}});
154 const gml::dvec3& p2,
155 const gml::dvec3& p3,
156 const gml::dvec3& color)
158 if(p1 == p2 || p2 == p3 || p1 == p3)
161 auto pp1 = project(p1);
162 auto pp2 = project(p2);
163 auto pp3 = project(p3);
165 if(cullface_ &&
gml::normal(pp1, pp2, pp3)[2] > 0.0)
168 elems_.push_back(std::unique_ptr<BaseElem>{
new TriangleElem(pp1, pp2, pp3, color)});
178 std::stringstream ss;
181 <<
"width=\"" << size_[0] <<
"\" height=\"" << size_[1] <<
"\" "
182 <<
"version=\"1.1\" "
183 <<
"xmlns=\"http://www.w3.org/2000/svg\""
187 <<
"width=\"" << size_[0] <<
"\" height=\"" << size_[1] <<
"\" "
188 <<
"style=\"fill:white\""
191 std::stable_sort(elems_.begin(),
193 [](
const std::unique_ptr<BaseElem>& e1,
const std::unique_ptr<BaseElem>& e2)
195 return e1->z_ > e2->z_;
198 for(
const auto& elem : elems_)
void viewport(int x, int y, int width, int height)
Sets the viewport. Default fills the whole image.
void modelView(const gml::dmat4 &matrix)
Sets the model view matrix. Default is the identity matrix.
void writeTriangle(const gml::dvec3 &p1, const gml::dvec3 &p2, const gml::dvec3 &p3, const gml::dvec3 &color)
Write one triangle.
svg_writer_t(int width, int height)
void writeLine(const gml::dvec3 &p1, const gml::dvec3 &p2, const gml::dvec3 &color={0.0, 0.0, 0.0})
Write one line.
void perspective(double fovy, double aspect, double zNear, double zFar)
void ortho(double left, double right, double bottom, double top)
std::string str() const
Generates svg xml from the data written so far.
void writePoint(const gml::dvec3 &p, const gml::dvec3 &color={0.0, 0.0, 0.0})
Write one point. Drawn as a circle.
void cullface(bool cullface)
Sets if backfacing triangles should be culled. Default is true.
glm::tvec3< T > normal(const glm::tvec3< T > &p1, const glm::tvec3< T > &p2, const glm::tvec3< T > &p3)
glm::tmat4x4< T > ortho2D(const T &left, const T &right, const T &bottom, const T &top)
glm::tvec3< T > project(const glm::tvec3< T > &v, const glm::tmat4x4< T > &modelViewProj, const glm::tvec2< TI > &viewportOrigin, const glm::tvec2< TS > &viewportSize)