#ifndef STAIRS_H #define STAIRS_H #include #include "../gl/GLHelper.h" #include "../gl/GLTriangles.h" #include "../Renderable.h" class Stairs : public Renderable { private: Floorplan::Floor* floor; GLTriangles parts; public: /** ctor */ Stairs(Floorplan::Floor* floor) : floor(floor) { ; } void initGL() override { build(); // parts.setDiffuse(":/res/gl/tex/granite1.jpg"); // parts.setNormalMap(":/res/gl/tex/granite1_normal.jpg"); parts.setDiffuse(":/res/gl/tex/floor4.jpg"); parts.setNormalMap(":/res/gl/tex/floor4_normal.jpg"); parts.build(); loadShader(":/res/gl/vertex1.glsl", ":/res/gl/fragmentTex.glsl"); program.setUniformValue("texDiffuse", 0); program.setUniformValue("texNormalMap", 1); } /** render the floor */ void _render(const RenderParams& params) override { (void) params; parts.render(&program); } private: void build() { for (Floorplan::Stair* stair : floor->stairs) { if (dynamic_cast(stair)) { Floorplan::StairFreeform* freeform = dynamic_cast(stair); add(Floorplan::getQuads(freeform->getParts(), floor)); } } } void add(const std::vector& quads) { for (const Floorplan::Quad3& quad : quads) { //void addQuad(quad); stepify(quad); } } void stepify(const Floorplan::Quad3& quad) { const float len = (quad.p4 - quad.p1).length(); const float stepLen = 0.3; const int steps = std::round(len / stepLen); for (int i = 0; i < steps; ++i) { const float per1 = (float) (i+0) / (float) steps; const float per2 = (float) (i+1) / (float) steps; const Point3 p1 = quad.p1 + (quad.p4 - quad.p1) * per1; const Point3 p2 = quad.p2 + (quad.p3 - quad.p2) * per1; const Point3 p5 = quad.p2 + (quad.p3 - quad.p2) * per2; const Point3 p6 = quad.p1 + (quad.p4 - quad.p1) * per2; Point3 p3 = p5; p3.z = p2.z; Point3 p4 = p6; p4.z = p1.z; addQuad(Floorplan::Quad3(p1, p2, p3, p4)); addQuad(Floorplan::Quad3(p3, p4, p6, p5)); } } void addQuad(const Floorplan::Quad3& quad) { const QVector3D vert1(quad.p1.x, quad.p1.z, quad.p1.y); const QVector3D vert2(quad.p2.x, quad.p2.z, quad.p2.y); const QVector3D vert3(quad.p3.x, quad.p3.z, quad.p3.y); const QVector3D vert4(quad.p4.x, quad.p4.z, quad.p4.y); const QVector3D n1 = GLHelper::getNormal(vert1, vert2, vert3); const QVector3D n2 = -n1; // const float o = // const QVector2D tex1(quad.p1.length(), quad.p1.y); // const QVector2D tex2(quad.p2.x, quad.p2.y+quad.p2.z); // const QVector2D tex3(quad.p3.x, quad.p3.y+quad.p3.z); // const QVector2D tex4(quad.p4.x, quad.p4.y+quad.p4.z); const float h = quad.p4.getDistance(quad.p1); const float l = quad.p1.getDistance(quad.p2); const float o = quad.p1.length(); const float s = 1.1; // 0.5; const QVector2D tex1(o+0, h); // start texturing at the ceiling so above-door-sections and walls have the same textre const QVector2D tex2(o+l, h); const QVector2D tex3(o+l, 0); const QVector2D tex4(o+0, 0); // const VertNormTex vnt1(vert1, n1, tex1*s); // const VertNormTex vnt2(vert2, n1, tex2*s); // const VertNormTex vnt3(vert3, n1, tex3*s); // const VertNormTex vnt4(vert4, n1, tex4*s); { const VertNormTex vnt1(vert1, n1, tex1*s); const VertNormTex vnt2(vert2, n1, tex2*s); const VertNormTex vnt3(vert3, n1, tex3*s); const VertNormTex vnt4(vert4, n1, tex4*s); parts.addQuadCCW(vnt1, vnt2, vnt3, vnt4); } { const VertNormTex vnt1(vert1, n2, tex1*s); const VertNormTex vnt2(vert2, n2, tex2*s); const VertNormTex vnt3(vert3, n2, tex3*s); const VertNormTex vnt4(vert4, n2, tex4*s); parts.addQuadCW(vnt1, vnt2, vnt3, vnt4); } } }; #endif // STAIRS_H