Code: Alles auswählen
void Foo::triangulate(
WallSurface & surface,
float const minimalHeight,
float const maximalHeight,
float const uOffset, // for continuous UV along loops
float const vOffset, // for continuous UV along loops
float const re,
float const gr,
float const bl
) {
growCapacity(vertices, 64);
growCapacity(pickingVertices, 32);
surface.startOfPickingTriangles = WallTriangleIndex(lengthOf(pickingVertices) / 3);
surface.startOfTriangles = WallTriangleIndex(lengthOf(vertices) / 3);
surface.yMinimum = minimalHeight;
surface.yMaximum = maximalHeight;
auto const & a = surface.from;
auto const & b = surface.to;
// Picking triangles:
{
// Connect the top of the surface to the anchors. This is required to avoid annoying picking issues.
auto const & anchorA = anchors[surface.anchors[0]].position;
auto const & anchorB = anchors[surface.anchors[1]].position;
Math::Point<float, 3> const points[] = {
{ a.x, minimalHeight, a.y },
{ b.x, minimalHeight, b.y },
{ b.x, maximalHeight, b.y },
{ a.x, maximalHeight, a.y },
{ anchorA.x, maximalHeight, anchorA.y },
{ anchorB.x, maximalHeight, anchorB.y }
};
// Front of the surface:
*pickingVertices.toEnd++ = points[0];
*pickingVertices.toEnd++ = points[1];
*pickingVertices.toEnd++ = points[2];
*pickingVertices.toEnd++ = points[0];
*pickingVertices.toEnd++ = points[2];
*pickingVertices.toEnd++ = points[3];
// Top:
*pickingVertices.toEnd++ = points[3];
*pickingVertices.toEnd++ = points[5];
*pickingVertices.toEnd++ = points[4];
*pickingVertices.toEnd++ = points[3];
*pickingVertices.toEnd++ = points[2];
*pickingVertices.toEnd++ = points[5];
}
// Connect the top of the surface to the anchors. It just looks so much better.
{
auto const & anchorA = anchors[surface.anchors[0]].position;
auto const & anchorB = anchors[surface.anchors[1]].position;
WallVertex const points[] = {
{ { b.x, maximalHeight, b.y }, { } },
{ { a.x, maximalHeight, a.y }, { } },
{ { anchorA.x, maximalHeight, anchorA.y }, { } },
{ { anchorB.x, maximalHeight, anchorB.y }, { } }
};
// Top:
*vertices.toEnd++ = points[1];
*vertices.toEnd++ = points[2];
*vertices.toEnd++ = points[3];
*vertices.toEnd++ = points[1];
*vertices.toEnd++ = points[3];
*vertices.toEnd++ = points[0];
}
auto const brightnessBottom = 0.2f;
auto const brightnessCenter = 0.5f;
auto const brightness_S_B = surface.brightnessStart * brightnessBottom;
auto const brightness_C_B = brightnessBottom;
auto const brightness_E_B = surface.brightnessEnd * brightnessBottom;
auto const brightness_S_C = surface.brightnessStart * brightnessCenter;
auto const brightness_C_C = brightnessCenter;
auto const brightness_E_C = surface.brightnessEnd * brightnessCenter;
auto const brightness_S_T = surface.brightnessStart;
auto const brightness_C_T = 1.0f;
auto const brightness_E_T = surface.brightnessEnd;
if(hasPortal(surface)) {
auto const & portal = portals[surface.portalIndex];
auto const length = distanceBetween(a, b); // * 0.5 because height is 2 (scale uniformly)
auto const halfWidth = 0.5f * portal.width;
auto const stepHeight = portal.heightBegin;
auto const totalHeight = portal.heightEnd;
MUST(portal.heightEnd <= maximalHeight);
auto const startToEndDirection = normalized(b - a);
auto const brightness_B = Math::interpolateLinearly(brightnessBottom, stepHeight / 2.0f, 1.0f);
auto const al = a + startToEndDirection * (0.5f * length - halfWidth);
auto const ar = a + startToEndDirection * (0.5f * length + halfWidth);
auto const & aa = anchors[surface.anchors[0]].position;
auto const & ab = anchors[surface.anchors[1]].position;
auto const alength = distanceBetween(ab, aa);
auto const aal = aa + startToEndDirection * (0.5f * alength - halfWidth);
auto const aar = aa + startToEndDirection * (0.5f * alength + halfWidth);
auto const uMin = uOffset;
auto const ual = uOffset + 0.5f * (0.5f * length - halfWidth); // * 0.5 because height is 2 (scale uniformly)
auto const uar = uOffset + 0.5f * (0.5f * length + halfWidth); // * 0.5 because height is 2 (scale uniformly)
auto const uMax = uOffset + 0.5f * length; // * 0.5 because height is 2 (scale uniformly)
auto const vMin = vOffset;
auto const vStep = vOffset + 0.5f * stepHeight;
auto const vTotal = vOffset + 0.5f * totalHeight;
auto const vMax = vOffset + 0.5f * maximalHeight;
// 0------1
// | 4--5 | 8--9
// | | | | | |
// | | | | | |
// | 6--7 | 10--11
// 2------3
WallVertex const vertz[] = {
{ { a.x, maximalHeight, a.y }, { uMin, vMax }, re, gr, bl },
{ { b.x, maximalHeight, b.y }, { uMax, vMax }, re, gr, bl },
{ { a.x, minimalHeight, a.y }, { uMin, vMin }, re * brightnessBottom, gr * brightnessBottom, bl * brightnessBottom },
{ { b.x, minimalHeight, b.y }, { uMax, vMin }, re * brightnessBottom, gr * brightnessBottom, bl * brightnessBottom },
{ { al.x, totalHeight, al.y }, { ual, vTotal }, re, gr, bl },
{ { ar.x, totalHeight, ar.y }, { uar, vTotal }, re, gr, bl },
{ { al.x, stepHeight, al.y }, { ual, vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
{ { ar.x, stepHeight, ar.y }, { uar, vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
{ { aal.x, totalHeight, aal.y }, { ual, vTotal }, 0.5f * re, 0.5f * gr, 0.5f * bl },
{ { aar.x, totalHeight, aar.y }, { uar, vTotal }, 0.5f * re, 0.5f * gr, 0.5f * bl },
{ { aal.x, stepHeight, aal.y }, { ual, vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B },
{ { aar.x, stepHeight, aar.y }, { uar, vStep }, re * brightness_B, gr * brightness_B, bl * brightness_B }
};
// Outsides
*vertices.toEnd++ = vertz[0];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[0];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[3];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[3];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[3];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[5];
// door insides
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[9];
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[10];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[11];
*vertices.toEnd++ = vertz[9];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[11];
*vertices.toEnd++ = vertz[5];
// If this is a door, then the triangles are already covered by the room's floor.
if(false == isDoor(portal)) {
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[10];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[10];
*vertices.toEnd++ = vertz[11];
}
} else {
auto const length = distanceBetween(surface.from, surface.to);
auto const uMin = uOffset;
auto const uMid = uOffset + 0.25f * length; // * 0.5 because height is 2 (scale uniformly)
auto const uMax = uOffset + 0.5f * length; // * 0.5 because height is 2 (scale uniformly)
auto const vMin = vOffset;
auto const vMid = vOffset + 0.25f * maximalHeight;
auto const vMax = vOffset + 0.5f * maximalHeight;
auto const ab = centerOf(a, b);
auto const halfHeight = Math::interpolateLinearly(minimalHeight, 0.5f, maximalHeight);
WallVertex const vertz[16] = {
{ { a.x, minimalHeight, a.y }, { uMin, vMin }, re * brightness_E_B, gr * brightness_E_B, bl * brightness_E_B, { } },
{ { ab.x, minimalHeight, ab.y }, { uMid, vMin }, re * brightness_C_B, gr * brightness_C_B, bl * brightness_C_B, { } },
{ { ab.x, halfHeight, ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
{ { a.x, halfHeight, a.y }, { uMin, vMid }, re * brightness_E_C, gr * brightness_E_C, bl * brightness_E_C, { } },
{ { b.x, minimalHeight, b.y }, { uMax, vMin }, re * brightness_S_B, gr * brightness_S_B, bl * brightness_S_B, { } },
{ { b.x, halfHeight, b.y }, { uMax, vMid }, re * brightness_S_C, gr * brightness_S_C, bl * brightness_S_C, { } },
{ { a.x, halfHeight, a.y }, { uMin, vMid }, re * brightness_E_C, gr * brightness_E_C, bl * brightness_E_C, { } },
#if _DEBUG
{ { ab.x, halfHeight, ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
{ { ab.x, maximalHeight, ab.y }, { uMid, vMax }, re * brightness_C_T, gr * brightness_C_T, bl * brightness_C_T, { } },
{ { a.x, maximalHeight, a.y }, { uMin, vMax }, re * brightness_E_T, gr * brightness_E_T, bl * brightness_E_T, { } },
{ { ab.x, halfHeight, ab.y }, { uMid, vMid }, re * brightness_C_C, gr * brightness_C_C, bl * brightness_C_C, { } },
{ { b.x, halfHeight, b.y }, { uMax, vMid }, re * brightness_S_C, gr * brightness_S_C, bl * brightness_S_C, { } },
{ { b.x, maximalHeight, b.y }, { uMax, vMax }, re * brightness_S_T, gr * brightness_S_T, bl * brightness_S_T, { } },
{ { ab.x, maximalHeight, ab.y }, { uMid, vMax }, re * brightness_C_T, gr * brightness_C_T, bl * brightness_C_T, { } }
#endif
};
*vertices.toEnd++ = vertz[0];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[0];
*vertices.toEnd++ = vertz[3];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[5];
*vertices.toEnd++ = vertz[4];
*vertices.toEnd++ = vertz[1];
*vertices.toEnd++ = vertz[2];
*vertices.toEnd++ = vertz[5];
#if _DEBUG
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[7];
*vertices.toEnd++ = vertz[6];
*vertices.toEnd++ = vertz[9];
*vertices.toEnd++ = vertz[8];
*vertices.toEnd++ = vertz[10];
*vertices.toEnd++ = vertz[12];
*vertices.toEnd++ = vertz[11];
*vertices.toEnd++ = vertz[10];
*vertices.toEnd++ = vertz[13];
*vertices.toEnd++ = vertz[12];
#endif
}
surface.endOfPickingTriangles = WallTriangleIndex(lengthOf(pickingVertices) / 3);
surface.endOfTriangles = WallTriangleIndex(lengthOf(vertices) / 3);
}
damit die Release-Version nicht abstürzt. Wenn ich das betreffende Array um 1 größer mache oder 2 Zuweisungen mehr einkommentiere, stürzt der Compiler ab. Gelöst habe ich es, indem ich die doppelten Variablen entfernt habe (dann gingen 9 Array-Elemente und 3 Zuweisungen mehr); und
geholt habe (dann ging alles).