mirror of
https://github.com/thorvg/thorvg.git
synced 2025-07-25 23:59:12 +00:00
wg_engine: merged math functions with common
issue: https://github.com/thorvg/thorvg/issues/2313
This commit is contained in:
parent
a26a386ccd
commit
1e9609c6f7
3 changed files with 109 additions and 68 deletions
|
@ -176,6 +176,24 @@ Point normal(const Point& p1, const Point& p2);
|
||||||
void normalize(Point& pt);
|
void normalize(Point& pt);
|
||||||
|
|
||||||
|
|
||||||
|
static inline Point min(const Point& lhs, const Point& rhs)
|
||||||
|
{
|
||||||
|
return {std::min(lhs.x, rhs.x), std::min(lhs.y, rhs.y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline Point max(const Point& lhs, const Point& rhs)
|
||||||
|
{
|
||||||
|
return {std::max(lhs.x, rhs.x), std::max(lhs.y, rhs.y)};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline float dot(const Point& lhs, const Point& rhs)
|
||||||
|
{
|
||||||
|
return lhs.x * rhs.x + lhs.y * rhs.y;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline bool zero(const Point& p)
|
static inline bool zero(const Point& p)
|
||||||
{
|
{
|
||||||
return tvg::zero(p.x) && tvg::zero(p.y);
|
return tvg::zero(p.x) && tvg::zero(p.y);
|
||||||
|
@ -200,6 +218,12 @@ static inline float length(const Point& a)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline float length2(const Point& a)
|
||||||
|
{
|
||||||
|
return a.x * a.x + a.y * a.y;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
static inline bool operator==(const Point& lhs, const Point& rhs)
|
static inline bool operator==(const Point& lhs, const Point& rhs)
|
||||||
{
|
{
|
||||||
return tvg::equal(lhs.x, rhs.x) && tvg::equal(lhs.y, rhs.y);
|
return tvg::equal(lhs.x, rhs.x) && tvg::equal(lhs.y, rhs.y);
|
||||||
|
@ -266,6 +290,12 @@ static inline Point operator/(const Point& lhs, const float rhs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static inline Point operator-(const Point& a)
|
||||||
|
{
|
||||||
|
return {-a.x, -a.y};
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void log(const Point& pt)
|
static inline void log(const Point& pt)
|
||||||
{
|
{
|
||||||
TVGLOG("COMMON", "Point: [%f %f]", pt.x, pt.y);
|
TVGLOG("COMMON", "Point: [%f %f]", pt.x, pt.y);
|
||||||
|
|
|
@ -1756,10 +1756,10 @@ void Stroker::strokeLineTo(const Point& curr)
|
||||||
mRightBottom.y = mLeftTop.y = curr.y;
|
mRightBottom.y = mLeftTop.y = curr.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
mLeftTop.x = std::min(mLeftTop.x, min(min(a.x, b.x), min(c.x, d.x)));
|
mLeftTop.x = std::min(mLeftTop.x, std::min(std::min(a.x, b.x), std::min(c.x, d.x)));
|
||||||
mLeftTop.y = std::min(mLeftTop.y, min(min(a.y, b.y), min(c.y, d.y)));
|
mLeftTop.y = std::min(mLeftTop.y, std::min(std::min(a.y, b.y), std::min(c.y, d.y)));
|
||||||
mRightBottom.x = std::max(mRightBottom.x, max(max(a.x, b.x), max(c.x, d.x)));
|
mRightBottom.x = std::max(mRightBottom.x, std::max(std::max(a.x, b.x), std::max(c.x, d.x)));
|
||||||
mRightBottom.y = std::max(mRightBottom.y, max(max(a.y, b.y), max(c.y, d.y)));
|
mRightBottom.y = std::max(mRightBottom.y, std::max(std::max(a.y, b.y), std::max(c.y, d.y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1839,10 +1839,10 @@ void Stroker::strokeRound(const Point &prev, const Point& curr, const Point& cen
|
||||||
{
|
{
|
||||||
if (_calcOrientation(prev, center, curr) == Orientation::Linear) return;
|
if (_calcOrientation(prev, center, curr) == Orientation::Linear) return;
|
||||||
|
|
||||||
mLeftTop.x = std::min(mLeftTop.x, min(center.x, min(prev.x, curr.x)));
|
mLeftTop.x = std::min(mLeftTop.x, std::min(center.x, std::min(prev.x, curr.x)));
|
||||||
mLeftTop.y = std::min(mLeftTop.y, min(center.y, min(prev.y, curr.y)));
|
mLeftTop.y = std::min(mLeftTop.y, std::min(center.y, std::min(prev.y, curr.y)));
|
||||||
mRightBottom.x = std::max(mRightBottom.x, max(center.x, max(prev.x, curr.x)));
|
mRightBottom.x = std::max(mRightBottom.x, std::max(center.x, std::max(prev.x, curr.x)));
|
||||||
mRightBottom.y = std::max(mRightBottom.y, max(center.y, max(prev.y, curr.y)));
|
mRightBottom.y = std::max(mRightBottom.y, std::max(center.y, std::max(prev.y, curr.y)));
|
||||||
|
|
||||||
// Fixme: just use bezier curve to calculate step count
|
// Fixme: just use bezier curve to calculate step count
|
||||||
auto count = _bezierCurveCount(_bezFromArc(prev, curr, strokeRadius()));
|
auto count = _bezierCurveCount(_bezFromArc(prev, curr, strokeRadius()));
|
||||||
|
@ -1943,10 +1943,10 @@ void Stroker::strokeSquare(const Point& p, const Point& outDir)
|
||||||
mResIndices->push(bi);
|
mResIndices->push(bi);
|
||||||
mResIndices->push(di);
|
mResIndices->push(di);
|
||||||
|
|
||||||
mLeftTop.x = std::min(mLeftTop.x, min(min(a.x, b.x), min(c.x, d.x)));
|
mLeftTop.x = std::min(mLeftTop.x, std::min(std::min(a.x, b.x), std::min(c.x, d.x)));
|
||||||
mLeftTop.y = std::min(mLeftTop.y, min(min(a.y, b.y), min(c.y, d.y)));
|
mLeftTop.y = std::min(mLeftTop.y, std::min(std::min(a.y, b.y), std::min(c.y, d.y)));
|
||||||
mRightBottom.x = std::max(mRightBottom.x, max(max(a.x, b.x), max(c.x, d.x)));
|
mRightBottom.x = std::max(mRightBottom.x, std::max(std::max(a.x, b.x), std::max(c.x, d.x)));
|
||||||
mRightBottom.y = std::max(mRightBottom.y, max(max(a.y, b.y), max(c.y, d.y)));
|
mRightBottom.y = std::max(mRightBottom.y, std::max(std::max(a.y, b.y), std::max(c.y, d.y)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2481,10 +2481,10 @@ uint32_t BWTessellator::pushVertex(float x, float y)
|
||||||
mRightBottom.x = mLeftTop.x = x;
|
mRightBottom.x = mLeftTop.x = x;
|
||||||
mRightBottom.y = mLeftTop.y = y;
|
mRightBottom.y = mLeftTop.y = y;
|
||||||
} else {
|
} else {
|
||||||
mLeftTop.x = min(mLeftTop.x, x);
|
mLeftTop.x = std::min(mLeftTop.x, x);
|
||||||
mLeftTop.y = min(mLeftTop.y, y);
|
mLeftTop.y = std::min(mLeftTop.y, y);
|
||||||
mRightBottom.x = max(mRightBottom.x, x);
|
mRightBottom.x = std::max(mRightBottom.x, x);
|
||||||
mRightBottom.y = max(mRightBottom.y , y);
|
mRightBottom.y = std::max(mRightBottom.y , y);
|
||||||
}
|
}
|
||||||
|
|
||||||
return index;
|
return index;
|
||||||
|
|
|
@ -24,26 +24,16 @@
|
||||||
#define _TVG_WG_GEOMETRY_H_
|
#define _TVG_WG_GEOMETRY_H_
|
||||||
|
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <functional>
|
|
||||||
#include "tvgMath.h"
|
#include "tvgMath.h"
|
||||||
#include "tvgRender.h"
|
#include "tvgRender.h"
|
||||||
|
|
||||||
// base vector operations
|
|
||||||
static Point operator-(const Point& a) { return {-a.x, -a.y}; }
|
|
||||||
static inline float length2(const Point& a) { return a.x*a.x+a.y*a.y; };
|
|
||||||
static inline float distance2(const Point& a, const Point& b) { return length2(a - b); };
|
|
||||||
static inline float distance(const Point& a, const Point& b) { return length(a - b); };
|
|
||||||
static inline float dot(const Point& a, const Point& b) { return a.x*b.x + a.y*b.y; };
|
|
||||||
static inline Point min(const Point& a, const Point& b) { return { std::min(a.x, b.x), std::min(a.y, b.y) }; };
|
|
||||||
static inline Point max(const Point& a, const Point& b) { return { std::max(a.x, b.x), std::max(a.y, b.y) }; };
|
|
||||||
static inline Point lerp(const Point& a, const Point& b, float t) { return a * (1.0f - t) + b * t; };
|
|
||||||
static inline Point normalize(const Point& a) { float rlen = 1.0f / length(a); return { a.x * rlen, a.y * rlen }; }
|
|
||||||
|
|
||||||
// default size of vertex and index buffers
|
// default size of vertex and index buffers
|
||||||
#define WG_POINTS_COUNT 32768
|
#define WG_POINTS_COUNT 32768
|
||||||
|
|
||||||
// simple vertex buffer
|
// simple vertex buffer
|
||||||
struct WgVertexBuffer {
|
struct WgVertexBuffer
|
||||||
|
{
|
||||||
Point vbuff[WG_POINTS_COUNT]; // vertex buffer
|
Point vbuff[WG_POINTS_COUNT]; // vertex buffer
|
||||||
float vdist[WG_POINTS_COUNT]; // distance to previous point
|
float vdist[WG_POINTS_COUNT]; // distance to previous point
|
||||||
float vleng[WG_POINTS_COUNT]; // distance to the first point through all previous points
|
float vleng[WG_POINTS_COUNT]; // distance to the first point through all previous points
|
||||||
|
@ -54,28 +44,33 @@ struct WgVertexBuffer {
|
||||||
using onPolylineFn = std::function<void(const WgVertexBuffer& buff)>;
|
using onPolylineFn = std::function<void(const WgVertexBuffer& buff)>;
|
||||||
|
|
||||||
// reset buffer
|
// reset buffer
|
||||||
void reset() {
|
void reset()
|
||||||
|
{
|
||||||
vcount = 0;
|
vcount = 0;
|
||||||
closed = false;
|
closed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the last point with optional index offset from the end
|
// get the last point with optional index offset from the end
|
||||||
Point last(size_t offset = 0) const {
|
Point last(size_t offset = 0) const
|
||||||
|
{
|
||||||
return vbuff[vcount - offset - 1];
|
return vbuff[vcount - offset - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get the last distance with optional index offset from the end
|
// get the last distance with optional index offset from the end
|
||||||
float lastDist(size_t offset = 0) const {
|
float lastDist(size_t offset = 0) const
|
||||||
|
{
|
||||||
return vdist[vcount - offset - 1];
|
return vdist[vcount - offset - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get total length
|
// get total length
|
||||||
float total() const {
|
float total() const
|
||||||
|
{
|
||||||
return (vcount == 0) ? 0.0f : vleng[vcount-1];
|
return (vcount == 0) ? 0.0f : vleng[vcount-1];
|
||||||
}
|
}
|
||||||
|
|
||||||
// get next vertex index by length using binary search
|
// get next vertex index by length using binary search
|
||||||
size_t getIndexByLength(float len) const {
|
size_t getIndexByLength(float len) const
|
||||||
|
{
|
||||||
if (vcount <= 1) return 0;
|
if (vcount <= 1) return 0;
|
||||||
size_t left = 0;
|
size_t left = 0;
|
||||||
size_t right = vcount - 1;
|
size_t right = vcount - 1;
|
||||||
|
@ -89,7 +84,8 @@ struct WgVertexBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// get min and max values of the buffer
|
// get min and max values of the buffer
|
||||||
void getMinMax(Point& pmin, Point& pmax) const {
|
void getMinMax(Point& pmin, Point& pmax) const
|
||||||
|
{
|
||||||
if (vcount == 0) return;
|
if (vcount == 0) return;
|
||||||
pmax = pmin = vbuff[0];
|
pmax = pmin = vbuff[0];
|
||||||
for (size_t i = 1; i < vcount; i++) {
|
for (size_t i = 1; i < vcount; i++) {
|
||||||
|
@ -99,38 +95,43 @@ struct WgVertexBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// update points distancess to the prev point and total length
|
// update points distancess to the prev point and total length
|
||||||
void updateDistances() {
|
void updateDistances()
|
||||||
|
{
|
||||||
if (vcount == 0) return;
|
if (vcount == 0) return;
|
||||||
vdist[0] = 0.0f;
|
vdist[0] = 0.0f;
|
||||||
vleng[0] = 0.0f;
|
vleng[0] = 0.0f;
|
||||||
for (size_t i = 1; i < vcount; i++) {
|
for (size_t i = 1; i < vcount; i++) {
|
||||||
vdist[i] = distance(vbuff[i-1], vbuff[i]);
|
vdist[i] = length(vbuff[i-1] - vbuff[i]);
|
||||||
vleng[i] = vleng[i-1] + vdist[i];
|
vleng[i] = vleng[i-1] + vdist[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// close vertex buffer
|
// close vertex buffer
|
||||||
void close() {
|
void close()
|
||||||
|
{
|
||||||
// check if last point is not to close to the first point
|
// check if last point is not to close to the first point
|
||||||
if (!tvg::zero(distance2(vbuff[0], last())))
|
if (!tvg::zero(length2(vbuff[0] - last())))
|
||||||
append(vbuff[0]);
|
append(vbuff[0]);
|
||||||
closed = true;
|
closed = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append point
|
// append point
|
||||||
void append(const Point& p) {
|
void append(const Point& p)
|
||||||
|
{
|
||||||
vbuff[vcount] = p;
|
vbuff[vcount] = p;
|
||||||
vcount++;
|
vcount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
// append source vertex buffer in index range from start to end (end not included)
|
// append source vertex buffer in index range from start to end (end not included)
|
||||||
void appendRange(const WgVertexBuffer& buff, size_t start_index, size_t end_index) {
|
void appendRange(const WgVertexBuffer& buff, size_t start_index, size_t end_index)
|
||||||
|
{
|
||||||
for (size_t i = start_index; i < end_index; i++)
|
for (size_t i = start_index; i < end_index; i++)
|
||||||
append(buff.vbuff[i]);
|
append(buff.vbuff[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append circle (list of triangles)
|
// append circle (list of triangles)
|
||||||
void appendCircle(float radius) {
|
void appendCircle(float radius)
|
||||||
|
{
|
||||||
// get approx circle length
|
// get approx circle length
|
||||||
float clen = 2.0f * radius * MATH_PI;
|
float clen = 2.0f * radius * MATH_PI;
|
||||||
size_t nsegs = std::max((uint32_t)(clen / 8), 16U);
|
size_t nsegs = std::max((uint32_t)(clen / 8), 16U);
|
||||||
|
@ -147,9 +148,10 @@ struct WgVertexBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// append cubic spline
|
// append cubic spline
|
||||||
void appendCubic(const Point& v0, const Point& v1, const Point& v2, const Point& v3) {
|
void appendCubic(const Point& v0, const Point& v1, const Point& v2, const Point& v3)
|
||||||
|
{
|
||||||
// get approx cubic length
|
// get approx cubic length
|
||||||
float clen = distance(v0, v1) + distance(v1, v2) + distance(v2, v3);
|
float clen = length(v0 - v1) + length(v1 - v2) + length(v2 - v3);
|
||||||
size_t nsegs = std::max((uint32_t)(clen / 8), 16U);
|
size_t nsegs = std::max((uint32_t)(clen / 8), 16U);
|
||||||
// append cubic
|
// append cubic
|
||||||
Bezier bezier{v0, v1, v2, v3};
|
Bezier bezier{v0, v1, v2, v3};
|
||||||
|
@ -158,7 +160,8 @@ struct WgVertexBuffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
// trim source buffer
|
// trim source buffer
|
||||||
void trim(const WgVertexBuffer& buff, float beg, float end) {
|
void trim(const WgVertexBuffer& buff, float beg, float end)
|
||||||
|
{
|
||||||
// empty buffer guard
|
// empty buffer guard
|
||||||
if (buff.vcount == 0) return;
|
if (buff.vcount == 0) return;
|
||||||
// initialize
|
// initialize
|
||||||
|
@ -183,7 +186,8 @@ struct WgVertexBuffer {
|
||||||
|
|
||||||
|
|
||||||
// decode path with callback for external prcesses
|
// decode path with callback for external prcesses
|
||||||
void decodePath(const RenderShape& rshape, bool update_dist, onPolylineFn onPolyline) {
|
void decodePath(const RenderShape& rshape, bool update_dist, onPolylineFn onPolyline)
|
||||||
|
{
|
||||||
// decode path
|
// decode path
|
||||||
reset();
|
reset();
|
||||||
size_t pntIndex = 0;
|
size_t pntIndex = 0;
|
||||||
|
@ -215,7 +219,8 @@ struct WgVertexBuffer {
|
||||||
};
|
};
|
||||||
|
|
||||||
// simple indexed vertex buffer
|
// simple indexed vertex buffer
|
||||||
struct WgVertexBufferInd {
|
struct WgVertexBufferInd
|
||||||
|
{
|
||||||
Point vbuff[WG_POINTS_COUNT*16];
|
Point vbuff[WG_POINTS_COUNT*16];
|
||||||
Point tbuff[WG_POINTS_COUNT*16];
|
Point tbuff[WG_POINTS_COUNT*16];
|
||||||
uint32_t ibuff[WG_POINTS_COUNT*16];
|
uint32_t ibuff[WG_POINTS_COUNT*16];
|
||||||
|
@ -223,12 +228,14 @@ struct WgVertexBufferInd {
|
||||||
size_t icount = 0;
|
size_t icount = 0;
|
||||||
|
|
||||||
// reset buffer
|
// reset buffer
|
||||||
void reset() {
|
void reset()
|
||||||
|
{
|
||||||
icount = vcount = 0;
|
icount = vcount = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
// get min and max values of the buffer
|
// get min and max values of the buffer
|
||||||
void getMinMax(Point& pmin, Point& pmax) const {
|
void getMinMax(Point& pmin, Point& pmax) const
|
||||||
|
{
|
||||||
if (vcount == 0) return;
|
if (vcount == 0) return;
|
||||||
pmax = pmin = vbuff[0];
|
pmax = pmin = vbuff[0];
|
||||||
for (size_t i = 1; i < vcount; i++) {
|
for (size_t i = 1; i < vcount; i++) {
|
||||||
|
@ -238,7 +245,8 @@ struct WgVertexBufferInd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// append quad - two triangles formed from four points
|
// append quad - two triangles formed from four points
|
||||||
void appendQuad(const Point& p0, const Point& p1, const Point& p2, const Point& p3) {
|
void appendQuad(const Point& p0, const Point& p1, const Point& p2, const Point& p3)
|
||||||
|
{
|
||||||
// append vertexes
|
// append vertexes
|
||||||
vbuff[vcount+0] = p0;
|
vbuff[vcount+0] = p0;
|
||||||
vbuff[vcount+1] = p1;
|
vbuff[vcount+1] = p1;
|
||||||
|
@ -257,7 +265,8 @@ struct WgVertexBufferInd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// dash buffer by pattern
|
// dash buffer by pattern
|
||||||
void appendStrokesDashed(const WgVertexBuffer& buff, const RenderStroke* rstroke) {
|
void appendStrokesDashed(const WgVertexBuffer& buff, const RenderStroke* rstroke)
|
||||||
|
{
|
||||||
// dashed buffer
|
// dashed buffer
|
||||||
WgVertexBuffer dashed;
|
WgVertexBuffer dashed;
|
||||||
dashed.reset();
|
dashed.reset();
|
||||||
|
@ -300,7 +309,8 @@ struct WgVertexBufferInd {
|
||||||
}
|
}
|
||||||
|
|
||||||
// append buffer with optional offset
|
// append buffer with optional offset
|
||||||
void appendBuffer(const WgVertexBuffer& buff, Point offset = Point{0.0f, 0.0f}) {
|
void appendBuffer(const WgVertexBuffer& buff, Point offset = Point{0.0f, 0.0f})
|
||||||
|
{
|
||||||
for (uint32_t i = 0; i < buff.vcount; i++ ) {
|
for (uint32_t i = 0; i < buff.vcount; i++ ) {
|
||||||
vbuff[vcount + i] = buff.vbuff[i] + offset;
|
vbuff[vcount + i] = buff.vbuff[i] + offset;
|
||||||
ibuff[icount + i] = vcount + i;
|
ibuff[icount + i] = vcount + i;
|
||||||
|
@ -309,15 +319,15 @@ struct WgVertexBufferInd {
|
||||||
icount += buff.vcount;
|
icount += buff.vcount;
|
||||||
};
|
};
|
||||||
|
|
||||||
// append line
|
void appendLine(const Point& v0, const Point& v1, float dist, float halfWidth)
|
||||||
void appendLine(const Point& v0, const Point& v1, float dist, float halfWidth) {
|
{
|
||||||
Point sub = v1 - v0;
|
Point sub = v1 - v0;
|
||||||
Point nrm = { +sub.y / dist * halfWidth, -sub.x / dist * halfWidth };
|
Point nrm = { +sub.y / dist * halfWidth, -sub.x / dist * halfWidth };
|
||||||
appendQuad(v0 - nrm, v0 + nrm, v1 - nrm, v1 + nrm);
|
appendQuad(v0 - nrm, v0 + nrm, v1 - nrm, v1 + nrm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append bevel joint
|
void appendBevel(const Point& v0, const Point& v1, const Point& v2, float dist1, float dist2, float halfWidth)
|
||||||
void appendBevel(const Point& v0, const Point& v1, const Point& v2, float dist1, float dist2, float halfWidth) {
|
{
|
||||||
Point sub1 = v1 - v0;
|
Point sub1 = v1 - v0;
|
||||||
Point sub2 = v2 - v1;
|
Point sub2 = v2 - v1;
|
||||||
Point nrm1 { +sub1.y / dist1 * halfWidth, -sub1.x / dist1 * halfWidth };
|
Point nrm1 { +sub1.y / dist1 * halfWidth, -sub1.x / dist1 * halfWidth };
|
||||||
|
@ -325,15 +335,16 @@ struct WgVertexBufferInd {
|
||||||
appendQuad(v1 - nrm1, v1 + nrm1, v1 - nrm2, v1 + nrm2);
|
appendQuad(v1 - nrm1, v1 + nrm1, v1 - nrm2, v1 + nrm2);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append miter joint
|
void appendMiter(const Point& v0, const Point& v1, const Point& v2, float dist1, float dist2, float halfWidth, float miterLimit)
|
||||||
void appendMiter(const Point& v0, const Point& v1, const Point& v2, float dist1, float dist2, float halfWidth, float miterLimit) {
|
{
|
||||||
Point sub1 = v1 - v0;
|
auto sub1 = v1 - v0;
|
||||||
Point sub2 = v2 - v1;
|
auto sub2 = v2 - v1;
|
||||||
Point nrm1 { +sub1.y / dist1, -sub1.x / dist1 };
|
auto nrm1 = Point{+sub1.y / dist1, -sub1.x / dist1};
|
||||||
Point nrm2 { +sub2.y / dist2, -sub2.x / dist2 };
|
auto nrm2 = Point{+sub2.y / dist2, -sub2.x / dist2};
|
||||||
Point offset1 = nrm1 * halfWidth;
|
auto offset1 = nrm1 * halfWidth;
|
||||||
Point offset2 = nrm2 * halfWidth;
|
auto offset2 = nrm2 * halfWidth;
|
||||||
Point nrm = normalize(nrm1 + nrm2);
|
auto nrm = nrm1 + nrm2;
|
||||||
|
normalize(nrm);
|
||||||
float cosine = dot(nrm, nrm1);
|
float cosine = dot(nrm, nrm1);
|
||||||
if (tvg::zero(cosine)) return;
|
if (tvg::zero(cosine)) return;
|
||||||
float angle = std::acos(dot(nrm1, -nrm2));
|
float angle = std::acos(dot(nrm1, -nrm2));
|
||||||
|
@ -347,16 +358,16 @@ struct WgVertexBufferInd {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// append square cap
|
void appendSquare(Point v0, Point v1, float dist, float halfWidth)
|
||||||
void appendSquare(Point v0, Point v1, float dist, float halfWidth) {
|
{
|
||||||
Point sub = v1 - v0;
|
Point sub = v1 - v0;
|
||||||
Point offset = sub / dist * halfWidth;
|
Point offset = sub / dist * halfWidth;
|
||||||
Point nrm = { +offset.y, -offset.x };
|
Point nrm = { +offset.y, -offset.x };
|
||||||
appendQuad(v1 - nrm, v1 + nrm, v1 + offset - nrm, v1 + offset + nrm);
|
appendQuad(v1 - nrm, v1 + nrm, v1 + offset - nrm, v1 + offset + nrm);
|
||||||
}
|
}
|
||||||
|
|
||||||
// append strokes
|
void appendStrokes(const WgVertexBuffer& buff, const RenderStroke* rstroke)
|
||||||
void appendStrokes(const WgVertexBuffer& buff, const RenderStroke* rstroke) {
|
{
|
||||||
assert(rstroke);
|
assert(rstroke);
|
||||||
// empty buffer gueard
|
// empty buffer gueard
|
||||||
if (buff.vcount < 2) return;
|
if (buff.vcount < 2) return;
|
||||||
|
|
Loading…
Add table
Reference in a new issue