Skip to content

Commit

Permalink
[spline/bezier]Improve bezier tessellator more.
Browse files Browse the repository at this point in the history
  • Loading branch information
xebra committed Oct 7, 2018
1 parent 068cc37 commit 4c6098d
Showing 1 changed file with 30 additions and 40 deletions.
70 changes: 30 additions & 40 deletions GPU/Common/SplineCommon.cpp
Expand Up @@ -92,15 +92,6 @@ class Bezier3DWeight {
} }
}; };


// http://en.wikipedia.org/wiki/Bernstein_polynomial
template<class T>
static T Bernstein3D(const T *p, const float w[4]) {
if (w[0] == 1) return p[0];
if (w[3] == 1) return p[3];
// Linear combination
return p[0] * w[0] + p[1] * w[1] + p[2] * w[2] + p[3] * w[3];
}

class Spline3DWeight { class Spline3DWeight {
private: private:
struct KnotDiv { struct KnotDiv {
Expand Down Expand Up @@ -509,8 +500,24 @@ struct PrecomputedCurves {
PrecomputedCurves(int count) { PrecomputedCurves(int count) {
} }


T Bernstein3D(int u, const float w[4]) { // http://en.wikipedia.org/wiki/Bernstein_polynomial
return ::Bernstein3D(horiz, w); template<class T>
static T Bernstein3D(const T p[4], const float w[4]) {
if (w[0] == 1) return p[0];
if (w[3] == 1) return p[3];
// Linear combination
return p[0] * w[0] + p[1] * w[1] + p[2] * w[2] + p[3] * w[3];
}

void Bernstein3D_U(const T *const p[16], const float w[4]) {
horiz[0] = Bernstein3D(p[0], w);
horiz[1] = Bernstein3D(p[4], w);
horiz[2] = Bernstein3D(p[8], w);
horiz[3] = Bernstein3D(p[12], w);
}

T Bernstein3D_V(const float w[4]) {
return Bernstein3D(horiz, w);
} }


T horiz[4]; T horiz[4];
Expand Down Expand Up @@ -549,39 +556,22 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
} }
for (int tile_u = 0; tile_u < tess_u + 1; ++tile_u) { for (int tile_u = 0; tile_u < tess_u + 1; ++tile_u) {
const Weight &wu = weights.u[tile_u]; const Weight &wu = weights.u[tile_u];
prepos.horiz[0] = Bernstein3D(_pos[0], wu.weights); prepos.Bernstein3D_U(_pos, wu.weights);
prepos.horiz[1] = Bernstein3D(_pos[4], wu.weights); if (sampleColors)
prepos.horiz[2] = Bernstein3D(_pos[8], wu.weights); precol.Bernstein3D_U(_col, wu.weights);
prepos.horiz[3] = Bernstein3D(_pos[12], wu.weights); if (sampleTexcoords)

pretex.Bernstein3D_U(_tex, wu.weights);
if (sampleColors) { if (computeNormals)
precol.horiz[0] = Bernstein3D(_col[0], wu.weights); prederivU.Bernstein3D_U(_pos, wu.derivs);
precol.horiz[1] = Bernstein3D(_col[4], wu.weights);
precol.horiz[2] = Bernstein3D(_col[8], wu.weights);
precol.horiz[3] = Bernstein3D(_col[12], wu.weights);
}
if (sampleTexcoords) {
pretex.horiz[0] = Bernstein3D(_tex[0], wu.weights);
pretex.horiz[1] = Bernstein3D(_tex[4], wu.weights);
pretex.horiz[2] = Bernstein3D(_tex[8], wu.weights);
pretex.horiz[3] = Bernstein3D(_tex[12], wu.weights);
}

if (computeNormals) {
prederivU.horiz[0] = Bernstein3D(_pos[0], wu.derivs);
prederivU.horiz[1] = Bernstein3D(_pos[4], wu.derivs);
prederivU.horiz[2] = Bernstein3D(_pos[8], wu.derivs);
prederivU.horiz[3] = Bernstein3D(_pos[12], wu.derivs);
}


for (int tile_v = 0; tile_v < tess_v + 1; ++tile_v) { for (int tile_v = 0; tile_v < tess_v + 1; ++tile_v) {


SimpleVertex &vert = vertices[tile_v * (tess_u + 1) + tile_u]; SimpleVertex &vert = vertices[tile_v * (tess_u + 1) + tile_u];


const Weight &wv = weights.v[tile_v]; const Weight &wv = weights.v[tile_v];
if (computeNormals) { if (computeNormals) {
const Vec3f derivU = prederivU.Bernstein3D(tile_u, wv.weights); const Vec3f derivU = prederivU.Bernstein3D_V(wv.weights);
const Vec3f derivV = prepos.Bernstein3D(tile_u, wv.derivs); const Vec3f derivV = prepos.Bernstein3D_V(wv.derivs);


vert.nrm = Cross(derivU, derivV).Normalized(); vert.nrm = Cross(derivU, derivV).Normalized();
if (patch.patchFacing) if (patch.patchFacing)
Expand All @@ -590,7 +580,7 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
vert.nrm.SetZero(); vert.nrm.SetZero();
} }


vert.pos = prepos.Bernstein3D(tile_u, wv.weights); vert.pos = prepos.Bernstein3D_V(wv.weights);


if (!sampleTexcoords) { if (!sampleTexcoords) {
float u = ((float)tile_u / (float)tess_u); float u = ((float)tile_u / (float)tess_u);
Expand All @@ -600,13 +590,13 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
vert.uv[1] = v + patch_u * third; vert.uv[1] = v + patch_u * third;
} else { } else {
// Sample UV from control points // Sample UV from control points
const Vec2f res = pretex.Bernstein3D(tile_u, wv.weights); const Vec2f res = pretex.Bernstein3D_V(wv.weights);
vert.uv[0] = res.x; vert.uv[0] = res.x;
vert.uv[1] = res.y; vert.uv[1] = res.y;
} }


if (sampleColors) { if (sampleColors) {
vert.color_32 = precol.Bernstein3D(tile_u, wv.weights).ToRGBA(); vert.color_32 = precol.Bernstein3D_V(wv.weights).ToRGBA();
} else { } else {
vert.color_32 = patch.defcolor; vert.color_32 = patch.defcolor;
} }
Expand Down

0 comments on commit 4c6098d

Please sign in to comment.