/* * © Copyright 2014 – Urheberrechtshinweis * Alle Rechte vorbehalten / All Rights Reserved * * Programmcode ist urheberrechtlich geschuetzt. * Das Urheberrecht liegt, soweit nicht ausdruecklich anders gekennzeichnet, bei Frank Ebner. * Keine Verwendung ohne explizite Genehmigung. * (vgl. § 106 ff UrhG / § 97 UrhG) */ #ifndef FLOORPLAN_3D_OBSTACLE3_H #define FLOORPLAN_3D_OBSTACLE3_H #include #include "../../geo/Triangle3.h" #include "../../geo/Sphere3.h" #include "../../geo/TriangleStrip3.h" #include "../v2/Floorplan.h" namespace Floorplan3D { /** * 3D obstacle * based on multiple triangles * has a material and a type */ struct Obstacle3D { enum class Type { UNKNOWN, GROUND_INDOOR, GROUND_OUTDOOR, STAIR, HANDRAIL, DOOR, WALL, WINDOW, OBJECT, ERROR, }; Type type; Floorplan::Material mat; std::vector triangles; /** empty ctor */ Obstacle3D() : type(Type::UNKNOWN), mat() {;} /** ctor */ Obstacle3D(Type type, Floorplan::Material mat) : type(type), mat(mat) {;} /** append a new triangle. REFERENCE ONLY VALID UNTIL NEXT ADD */ Triangle3& addTriangle(const Point3 p1, const Point3 p2, const Point3 p3, const bool reverse) { Triangle3 t(p1, p2, p3); if (reverse) {t.reverse();} triangles.push_back(t); return triangles.back(); } void addTriangleStrip(std::initializer_list pts, bool reverse = false) { TriangleStrip3 strip; for (const Point3& p : pts) {strip.add(p);} for (Triangle3 t : strip.toTriangles()) { if (reverse) {t.reverse();} triangles.push_back(t); } } void addTriangleStrip(const std::vector& pts, bool reverse = false) { TriangleStrip3 strip; for (const Point3& p : pts) {strip.add(p);} for (Triangle3 t : strip.toTriangles()) { if (reverse) {t.reverse();} triangles.push_back(t); } } /** append a new quad by splitting into two triangles */ void addQuad(const Point3 p1, const Point3 p2, const Point3 p3, const Point3 p4, const bool reverse = false) { addTriangle(p1, p2, p3, reverse); addTriangle(p1, p3, p4, reverse); } /** reverse all faces (CW<->CCW) */ void reverseFaces() { for (Triangle3& t : triangles) { t.reverse(); } } /** scaled copy */ Obstacle3D scaled(const Point3 scale) const { Obstacle3D copy = *this; for (Triangle3& tria : copy.triangles) { tria *= scale; } return copy; } /** translated copy */ Obstacle3D translated(const Point3 pos) const { Obstacle3D copy = *this; for (Triangle3& tria : copy.triangles) { tria += pos; } return copy; } /** rotated [around (0,0,0)] copy */ Obstacle3D rotated_deg(const Point3 rot) const { Obstacle3D copy = *this; for (Triangle3& tria : copy.triangles) { // tria.p1 = tria.p1.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); // tria.p2 = tria.p2.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); // tria.p3 = tria.p3.rot(rot.x/180.0f*M_PI, rot.y/180.0f*M_PI, rot.z/180.0f*M_PI); tria.rotate_deg(rot); } return copy; } /** get all triangle-edge-points (x,y) within the obstacle */ std::vector getPoints2D() const { std::vector res; for (const Triangle3& tria : triangles) { res.push_back(tria.p1.xy()); res.push_back(tria.p2.xy()); res.push_back(tria.p3.xy()); } return res; } /** get all triangle-edge-points (x,y,z) within the obstacle */ std::vector getPoints3D() const { std::vector res; for (const Triangle3& tria : triangles) { res.push_back(tria.p1); res.push_back(tria.p2); res.push_back(tria.p3); } return res; } /** perform sanity checks */ bool isValid() const { for (const Triangle3& t : triangles) { if (!t.isValid()) {return false;} } return true; } }; } #endif // FLOORPLAN_3D_OBSTACLE3_H