Skip to content

Commit

Permalink
Simplify some repeated code patterns a bit.
Browse files Browse the repository at this point in the history
Doesn't save many lines of actual code, though...
  • Loading branch information
unknownbrackets committed Apr 10, 2016
1 parent 555c76d commit c0660c5
Showing 1 changed file with 51 additions and 62 deletions.
113 changes: 51 additions & 62 deletions GPU/Common/SplineCommon.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -628,6 +628,32 @@ static void _BezierPatchLowQuality(u8 *&dest, u16 *&indices, int &count, int tes
}
}

template <typename T>
struct PrecomputedCurves {
PrecomputedCurves(int count) {
horiz1 = (T *)AllocateAlignedMemory(count * 4 * sizeof(T), 16);
horiz2 = horiz1 + count * 1;
horiz3 = horiz1 + count * 2;
horiz4 = horiz1 + count * 3;
}
~PrecomputedCurves() {
FreeAlignedMemory(horiz1);
}

T Bernstein3D(int u, float bv) {
return ::Bernstein3D(horiz1[u], horiz2[u], horiz3[u], horiz4[u], bv);
}

T Bernstein3DDerivative(int u, float bv) {
return ::Bernstein3DDerivative(horiz1[u], horiz2[u], horiz3[u], horiz4[u], bv);
}

T *horiz1;
T *horiz2;
T *horiz3;
T *horiz4;
};

static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType, int maxVertices) {
const float third = 1.0f / 3.0f;

Expand All @@ -640,25 +666,10 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
// First compute all the vertices and put them in an array
SimpleVertex *&vertices = (SimpleVertex*&)dest;

Vec3f *posHoriz1 = (Vec3f *)AllocateAlignedMemory((tess_u + 1) * 4 * sizeof(Vec3f), 16);
Vec3f *posHoriz2 = posHoriz1 + (tess_u + 1) * 1;
Vec3f *posHoriz3 = posHoriz1 + (tess_u + 1) * 2;
Vec3f *posHoriz4 = posHoriz1 + (tess_u + 1) * 3;

Vec4f *colHoriz1 = (Vec4f *)AllocateAlignedMemory((tess_u + 1) * 4 * sizeof(Vec4f), 16);
Vec4f *colHoriz2 = colHoriz1 + (tess_u + 1) * 1;
Vec4f *colHoriz3 = colHoriz1 + (tess_u + 1) * 2;
Vec4f *colHoriz4 = colHoriz1 + (tess_u + 1) * 3;

Math3D::Vec2f *texHoriz1 = (Math3D::Vec2f *)AllocateAlignedMemory((tess_u + 1) * 4 * sizeof(Math3D::Vec2f), 16);
Math3D::Vec2f *texHoriz2 = texHoriz1 + (tess_u + 1) * 1;
Math3D::Vec2f *texHoriz3 = texHoriz1 + (tess_u + 1) * 2;
Math3D::Vec2f *texHoriz4 = texHoriz1 + (tess_u + 1) * 3;

Vec3f *derivU1 = (Vec3f *)AllocateAlignedMemory((tess_u + 1) * 4 * sizeof(Vec3f), 16);
Vec3f *derivU2 = derivU1 + (tess_u + 1) * 1;
Vec3f *derivU3 = derivU1 + (tess_u + 1) * 2;
Vec3f *derivU4 = derivU1 + (tess_u + 1) * 3;
PrecomputedCurves<Vec3f> prepos(tess_u + 1);
PrecomputedCurves<Vec4f> precol(tess_u + 1);
PrecomputedCurves<Math3D::Vec2f> pretex(tess_u + 1);
PrecomputedCurves<Vec3f> prederivU(tess_u + 1);

const bool computeNormals = patch.computeNormals;
const bool sampleColors = (origVertType & GE_VTYPE_COL_MASK) != 0;
Expand All @@ -667,29 +678,29 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
// Precompute the horizontal curves to we only have to evaluate the vertical ones.
for (int i = 0; i < tess_u + 1; i++) {
float u = ((float)i / (float)tess_u);
posHoriz1[i] = Bernstein3D(patch.points[0]->pos, patch.points[1]->pos, patch.points[2]->pos, patch.points[3]->pos, u);
posHoriz2[i] = Bernstein3D(patch.points[4]->pos, patch.points[5]->pos, patch.points[6]->pos, patch.points[7]->pos, u);
posHoriz3[i] = Bernstein3D(patch.points[8]->pos, patch.points[9]->pos, patch.points[10]->pos, patch.points[11]->pos, u);
posHoriz4[i] = Bernstein3D(patch.points[12]->pos, patch.points[13]->pos, patch.points[14]->pos, patch.points[15]->pos, u);
prepos.horiz1[i] = Bernstein3D(patch.points[0]->pos, patch.points[1]->pos, patch.points[2]->pos, patch.points[3]->pos, u);
prepos.horiz2[i] = Bernstein3D(patch.points[4]->pos, patch.points[5]->pos, patch.points[6]->pos, patch.points[7]->pos, u);
prepos.horiz3[i] = Bernstein3D(patch.points[8]->pos, patch.points[9]->pos, patch.points[10]->pos, patch.points[11]->pos, u);
prepos.horiz4[i] = Bernstein3D(patch.points[12]->pos, patch.points[13]->pos, patch.points[14]->pos, patch.points[15]->pos, u);

if (sampleColors) {
colHoriz1[i] = Bernstein3D(patch.points[0]->color_32, patch.points[1]->color_32, patch.points[2]->color_32, patch.points[3]->color_32, u);
colHoriz2[i] = Bernstein3D(patch.points[4]->color_32, patch.points[5]->color_32, patch.points[6]->color_32, patch.points[7]->color_32, u);
colHoriz3[i] = Bernstein3D(patch.points[8]->color_32, patch.points[9]->color_32, patch.points[10]->color_32, patch.points[11]->color_32, u);
colHoriz4[i] = Bernstein3D(patch.points[12]->color_32, patch.points[13]->color_32, patch.points[14]->color_32, patch.points[15]->color_32, u);
precol.horiz1[i] = Bernstein3D(patch.points[0]->color_32, patch.points[1]->color_32, patch.points[2]->color_32, patch.points[3]->color_32, u);
precol.horiz2[i] = Bernstein3D(patch.points[4]->color_32, patch.points[5]->color_32, patch.points[6]->color_32, patch.points[7]->color_32, u);
precol.horiz3[i] = Bernstein3D(patch.points[8]->color_32, patch.points[9]->color_32, patch.points[10]->color_32, patch.points[11]->color_32, u);
precol.horiz4[i] = Bernstein3D(patch.points[12]->color_32, patch.points[13]->color_32, patch.points[14]->color_32, patch.points[15]->color_32, u);
}
if (sampleTexcoords) {
texHoriz1[i] = Bernstein3D(Math3D::Vec2f(patch.points[0]->uv), Math3D::Vec2f(patch.points[1]->uv), Math3D::Vec2f(patch.points[2]->uv), Math3D::Vec2f(patch.points[3]->uv), u);
texHoriz2[i] = Bernstein3D(Math3D::Vec2f(patch.points[4]->uv), Math3D::Vec2f(patch.points[5]->uv), Math3D::Vec2f(patch.points[6]->uv), Math3D::Vec2f(patch.points[7]->uv), u);
texHoriz3[i] = Bernstein3D(Math3D::Vec2f(patch.points[8]->uv), Math3D::Vec2f(patch.points[9]->uv), Math3D::Vec2f(patch.points[10]->uv), Math3D::Vec2f(patch.points[11]->uv), u);
texHoriz4[i] = Bernstein3D(Math3D::Vec2f(patch.points[12]->uv), Math3D::Vec2f(patch.points[13]->uv), Math3D::Vec2f(patch.points[14]->uv), Math3D::Vec2f(patch.points[15]->uv), u);
pretex.horiz1[i] = Bernstein3D(Math3D::Vec2f(patch.points[0]->uv), Math3D::Vec2f(patch.points[1]->uv), Math3D::Vec2f(patch.points[2]->uv), Math3D::Vec2f(patch.points[3]->uv), u);
pretex.horiz2[i] = Bernstein3D(Math3D::Vec2f(patch.points[4]->uv), Math3D::Vec2f(patch.points[5]->uv), Math3D::Vec2f(patch.points[6]->uv), Math3D::Vec2f(patch.points[7]->uv), u);
pretex.horiz3[i] = Bernstein3D(Math3D::Vec2f(patch.points[8]->uv), Math3D::Vec2f(patch.points[9]->uv), Math3D::Vec2f(patch.points[10]->uv), Math3D::Vec2f(patch.points[11]->uv), u);
pretex.horiz4[i] = Bernstein3D(Math3D::Vec2f(patch.points[12]->uv), Math3D::Vec2f(patch.points[13]->uv), Math3D::Vec2f(patch.points[14]->uv), Math3D::Vec2f(patch.points[15]->uv), u);
}

if (computeNormals) {
derivU1[i] = Bernstein3DDerivative(patch.points[0]->pos, patch.points[1]->pos, patch.points[2]->pos, patch.points[3]->pos, u);
derivU2[i] = Bernstein3DDerivative(patch.points[4]->pos, patch.points[5]->pos, patch.points[6]->pos, patch.points[7]->pos, u);
derivU3[i] = Bernstein3DDerivative(patch.points[8]->pos, patch.points[9]->pos, patch.points[10]->pos, patch.points[11]->pos, u);
derivU4[i] = Bernstein3DDerivative(patch.points[12]->pos, patch.points[13]->pos, patch.points[14]->pos, patch.points[15]->pos, u);
prederivU.horiz1[i] = Bernstein3DDerivative(patch.points[0]->pos, patch.points[1]->pos, patch.points[2]->pos, patch.points[3]->pos, u);
prederivU.horiz2[i] = Bernstein3DDerivative(patch.points[4]->pos, patch.points[5]->pos, patch.points[6]->pos, patch.points[7]->pos, u);
prederivU.horiz3[i] = Bernstein3DDerivative(patch.points[8]->pos, patch.points[9]->pos, patch.points[10]->pos, patch.points[11]->pos, u);
prederivU.horiz4[i] = Bernstein3DDerivative(patch.points[12]->pos, patch.points[13]->pos, patch.points[14]->pos, patch.points[15]->pos, u);
}
}

Expand All @@ -700,21 +711,11 @@ static void _BezierPatchHighQuality(u8 *&dest, u16 *&indices, int &count, int te
float v = ((float)tile_v / (float)tess_v);
float bv = v;

const Vec3f &pos1 = posHoriz1[tile_u];
const Vec3f &pos2 = posHoriz2[tile_u];
const Vec3f &pos3 = posHoriz3[tile_u];
const Vec3f &pos4 = posHoriz4[tile_u];

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

if (computeNormals) {
const Vec3f &derivU1_ = derivU1[tile_u];
const Vec3f &derivU2_ = derivU2[tile_u];
const Vec3f &derivU3_ = derivU3[tile_u];
const Vec3f &derivU4_ = derivU4[tile_u];

Vec3f derivU = Bernstein3D(derivU1_, derivU2_, derivU3_, derivU4_, bv);
Vec3f derivV = Bernstein3DDerivative(pos1, pos2, pos3, pos4, bv);
const Vec3f derivU = prederivU.Bernstein3D(tile_u, bv);
const Vec3f derivV = prepos.Bernstein3DDerivative(tile_u, bv);

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

vert.pos = Bernstein3D(pos1, pos2, pos3, pos4, bv);
vert.pos = prepos.Bernstein3D(tile_u, bv);

if (!sampleTexcoords) {
// Generate texcoord
vert.uv[0] = u + patch.u_index * third;
vert.uv[1] = v + patch.v_index * third;
} else {
// Sample UV from control points
const Math3D::Vec2f &tex1 = texHoriz1[tile_u];
const Math3D::Vec2f &tex2 = texHoriz2[tile_u];
const Math3D::Vec2f &tex3 = texHoriz3[tile_u];
const Math3D::Vec2f &tex4 = texHoriz4[tile_u];
const Math3D::Vec2f res = Bernstein3D(tex1, tex2, tex3, tex4, bv);
const Math3D::Vec2f res = pretex.Bernstein3D(tile_u, bv);
vert.uv[0] = res.x;
vert.uv[1] = res.y;
}

if (sampleColors) {
const Vec4f &col1 = colHoriz1[tile_u];
const Vec4f &col2 = colHoriz2[tile_u];
const Vec4f &col3 = colHoriz3[tile_u];
const Vec4f &col4 = colHoriz4[tile_u];
vert.color_32 = Bernstein3D(col1, col2, col3, col4, bv).ToRGBA();
vert.color_32 = precol.Bernstein3D(tile_u, bv).ToRGBA();
} else {
memcpy(vert.color, patch.points[0]->color, 4);
}
}
}
FreeAlignedMemory(derivU1);
FreeAlignedMemory(texHoriz1);
FreeAlignedMemory(colHoriz1);
FreeAlignedMemory(posHoriz1);

GEPatchPrimType prim_type = patch.primType;
// Combine the vertices into triangles.
Expand Down

0 comments on commit c0660c5

Please sign in to comment.