diff --git a/algoim/organizer/primitive.hpp b/algoim/organizer/primitive.hpp index f75df37..fb16bee 100644 --- a/algoim/organizer/primitive.hpp +++ b/algoim/organizer/primitive.hpp @@ -632,6 +632,32 @@ public: void print() override { std::cout << "Cone Description" << std::endl; } }; +class HalfPlaneDesc : virtual public PrimitiveDesc +{ +public: + // 基点,法向 + uvector3 basePt, normal; + + HalfPlaneDesc(const uvector3& basePt_, const uvector3& normal_) : PrimitiveDesc(), basePt(basePt_), normal(normal_) {} + + // 所有点应该位于一个面 + // 点顺序满足:叉乘指向法向,如 A B C D4点,ABxBC 与 BCxCD 与 normal同向 + HalfPlaneDesc(const std::vector& vertices) + { + assert(vertices.size() >= 3); + uvector3 V01 = vertices[1] - vertices[0]; + uvector3 v02 = vertices[2] - vertices[0]; + normal = cross(V01, v02); + normal /= norm(normal); + real d = -dot(normal, vertices[0]); + basePt = vertices[0]; + // test other vertices + for (int i = 3; i < vertices.size(); ++i) { + assert(dot(normal, vertices[i]) + d < std::numeric_limits::epsilon()); + } + } +}; + class MeshDesc : virtual public PrimitiveDesc { public: @@ -714,6 +740,21 @@ struct Scene { AABB boundary; }; +void makeHalfPlane(const HalfPlaneDesc& halfPlaneDesc, VisiblePrimitiveRep& visiblePrimitive) +{ + assert(visiblePrimitive.tensors.size() == 1); + auto& tensor = visiblePrimitive.tensors[0]; + assert(all(tensor.ext() == 3)); + xarrayInit(tensor); + tensor.m(uvector3(0, 0, 0)) = -dot(halfPlaneDesc.normal, halfPlaneDesc.basePt); + tensor.m(uvector3(1, 0, 0)) = halfPlaneDesc.normal(0); + tensor.m(uvector3(0, 1, 0)) = halfPlaneDesc.normal(1); + tensor.m(uvector3(0, 0, 1)) = halfPlaneDesc.normal(2); + + // AABB + visiblePrimitive.aabb.extend(halfPlaneDesc.basePt); +} + void makeMesh(const MeshDesc& mesh, VisiblePrimitiveRep& visiblePrimitive) { assert(visiblePrimitive.tensors.size() == mesh.indexInclusiveScan.size());