static void _BezierPatchLowQuality(u8 *&dest, u16 *&indices, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) { const float third = 1.0f / 3.0f; // Fast and easy way - just draw the control points, generate some very basic normal vector subsitutes. // Very inaccurate though but okay for Loco Roco. Maybe should keep it as an option. float u_base = patch.u_index / 3.0f; float v_base = patch.v_index / 3.0f; GEPatchPrimType prim_type = patch.primType; for (int tile_v = 0; tile_v < 3; tile_v++) { for (int tile_u = 0; tile_u < 3; tile_u++) { int point_index = tile_u + tile_v * 4; SimpleVertex v0 = *patch.points[point_index]; SimpleVertex v1 = *patch.points[point_index + 1]; SimpleVertex v2 = *patch.points[point_index + 4]; SimpleVertex v3 = *patch.points[point_index + 5]; // Generate UV. TODO: Do this even if UV specified in control points? if ((origVertType & GE_VTYPE_TC_MASK) == 0) { float u = u_base + tile_u * third; float v = v_base + tile_v * third; v0.uv[0] = u; v0.uv[1] = v; v1.uv[0] = u + third; v1.uv[1] = v; v2.uv[0] = u; v2.uv[1] = v + third; v3.uv[0] = u + third; v3.uv[1] = v + third; } // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. if (patch.computeNormals) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); if (patch.patchFacing) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; v2.nrm = norm; v3.nrm = norm; } int total = patch.index * 3 * 3 * 4; // A patch has 3x3 tiles, and each tiles have 4 vertices. int tile_index = tile_u + tile_v * 3; int idx0 = total + tile_index * 4 + 0; int idx1 = total + tile_index * 4 + 1; int idx2 = total + tile_index * 4 + 2; int idx3 = total + tile_index * 4 + 3; CopyQuad(dest, &v0, &v1, &v2, &v3); CopyQuadIndex(indices, prim_type, idx0, idx1, idx2, idx3); count += 6; } } }
void _SplinePatchLowQuality(u8 *&dest, int &count, const SplinePatchLocal &spatch, u32 origVertType) { const float third = 1.0f / 3.0f; // Fast and easy way - just draw the control points, generate some very basic normal vector substitutes. // Very inaccurate but okay for Loco Roco. Maybe should keep it as an option because it's fast. const int tile_min_u = (spatch.type_u & START_OPEN) ? 0 : 1; const int tile_min_v = (spatch.type_v & START_OPEN) ? 0 : 1; const int tile_max_u = (spatch.type_u & END_OPEN) ? spatch.count_u - 1 : spatch.count_u - 2; const int tile_max_v = (spatch.type_v & END_OPEN) ? spatch.count_v - 1 : spatch.count_v - 2; for (int tile_v = tile_min_v; tile_v < tile_max_v; ++tile_v) { for (int tile_u = tile_min_u; tile_u < tile_max_u; ++tile_u) { int point_index = tile_u + tile_v * spatch.count_u; SimpleVertex v0 = *spatch.points[point_index]; SimpleVertex v1 = *spatch.points[point_index + 1]; SimpleVertex v2 = *spatch.points[point_index + spatch.count_u]; SimpleVertex v3 = *spatch.points[point_index + spatch.count_u + 1]; // Generate UV. TODO: Do this even if UV specified in control points? if ((origVertType & GE_VTYPE_TC_MASK) == 0) { float u = tile_u * third; float v = tile_v * third; v0.uv[0] = u; v0.uv[1] = v; v1.uv[0] = u + third; v1.uv[1] = v; v2.uv[0] = u; v2.uv[1] = v + third; v3.uv[0] = u + third; v3.uv[1] = v + third; } // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. if (gstate.isLightingEnabled()) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); if (gstate.patchfacing & 1) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; v2.nrm = norm; v3.nrm = norm; } CopyQuad(dest, &v0, &v1, &v2, &v3); count += 6; } } }
void _BezierPatchLowQuality(u8 *&dest, int &count, int tess_u, int tess_v, const BezierPatch &patch, u32 origVertType) { const float third = 1.0f / 3.0f; // Fast and easy way - just draw the control points, generate some very basic normal vector subsitutes. // Very inaccurate though but okay for Loco Roco. Maybe should keep it as an option. float u_base = patch.u_index / 3.0f; float v_base = patch.v_index / 3.0f; for (int tile_v = 0; tile_v < 3; tile_v++) { for (int tile_u = 0; tile_u < 3; tile_u++) { int point_index = tile_u + tile_v * 4; SimpleVertex v0 = *patch.points[point_index]; SimpleVertex v1 = *patch.points[point_index + 1]; SimpleVertex v2 = *patch.points[point_index + 4]; SimpleVertex v3 = *patch.points[point_index + 5]; // Generate UV. TODO: Do this even if UV specified in control points? if ((origVertType & GE_VTYPE_TC_MASK) == 0) { float u = u_base + tile_u * third; float v = v_base + tile_v * third; v0.uv[0] = u; v0.uv[1] = v; v1.uv[0] = u + third; v1.uv[1] = v; v2.uv[0] = u; v2.uv[1] = v + third; v3.uv[0] = u + third; v3.uv[1] = v + third; } // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. if (gstate.isLightingEnabled()) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); if (gstate.patchfacing & 1) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; v2.nrm = norm; v3.nrm = norm; } CopyQuad(dest, &v0, &v1, &v2, &v3); count += 6; } } }
static inline void AccumulateWeighted(Vec3f &out, const Vec3Packedf &in, const Vec4f &w) { #ifdef _M_SSE out.vec = _mm_add_ps(out.vec, _mm_mul_ps(_mm_loadu_ps(in.AsArray()), w.vec)); #else out += in * w.x; #endif }
static void _SplinePatchLowQuality(u8 *&dest, u16 *indices, int &count, const SplinePatchLocal &spatch, u32 origVertType) { // Fast and easy way - just draw the control points, generate some very basic normal vector substitutes. // Very inaccurate but okay for Loco Roco. Maybe should keep it as an option because it's fast. const int tile_min_u = (spatch.type_u & START_OPEN) ? 0 : 1; const int tile_min_v = (spatch.type_v & START_OPEN) ? 0 : 1; const int tile_max_u = (spatch.type_u & END_OPEN) ? spatch.count_u - 1 : spatch.count_u - 2; const int tile_max_v = (spatch.type_v & END_OPEN) ? spatch.count_v - 1 : spatch.count_v - 2; float tu_width = (float)spatch.count_u - 3.0f; float tv_height = (float)spatch.count_v - 3.0f; tu_width /= (float)(tile_max_u - tile_min_u); tv_height /= (float)(tile_max_v - tile_min_v); GEPatchPrimType prim_type = spatch.primType; bool computeNormals = spatch.computeNormals; bool patchFacing = spatch.patchFacing; int i = 0; for (int tile_v = tile_min_v; tile_v < tile_max_v; ++tile_v) { for (int tile_u = tile_min_u; tile_u < tile_max_u; ++tile_u) { int point_index = tile_u + tile_v * spatch.count_u; SimpleVertex v0 = *spatch.points[point_index]; SimpleVertex v1 = *spatch.points[point_index + 1]; SimpleVertex v2 = *spatch.points[point_index + spatch.count_u]; SimpleVertex v3 = *spatch.points[point_index + spatch.count_u + 1]; // Generate UV. TODO: Do this even if UV specified in control points? if ((origVertType & GE_VTYPE_TC_MASK) == 0) { float u = (tile_u - tile_min_u) * tu_width; float v = (tile_v - tile_min_v) * tv_height; v0.uv[0] = u; v0.uv[1] = v; v1.uv[0] = u + tu_width; v1.uv[1] = v; v2.uv[0] = u; v2.uv[1] = v + tv_height; v3.uv[0] = u + tu_width; v3.uv[1] = v + tv_height; } // Generate normal if lighting is enabled (otherwise there's no point). // This is a really poor quality algorithm, we get facet normals. if (computeNormals) { Vec3Packedf norm = Cross(v1.pos - v0.pos, v2.pos - v0.pos); norm.Normalize(); if (patchFacing) norm *= -1.0f; v0.nrm = norm; v1.nrm = norm; v2.nrm = norm; v3.nrm = norm; } int idx0 = i * 4 + 0; int idx1 = i * 4 + 1; int idx2 = i * 4 + 2; int idx3 = i * 4 + 3; i++; CopyQuad(dest, &v0, &v1, &v2, &v3); CopyQuadIndex(indices, prim_type, idx0, idx1, idx2, idx3); count += 6; } } }