[spline/bezier]Improve bezier tessellator more.
This commit is contained in:
parent
068cc37b2f
commit
4c6098d801
1 changed files with 30 additions and 40 deletions
|
@ -92,15 +92,6 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 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 {
|
||||||
|
@ -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];
|
||||||
|
@ -549,30 +556,13 @@ 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) {
|
||||||
|
|
||||||
|
@ -580,8 +570,8 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
|
||||||
|
|
||||||
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)
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue