#include "stdafx.h" #include "ReadXML.h" #include #include #include #include #include #include #include using namespace std; inline bool PointInTri(Point3 &P, Point3 &P0, Point3 &P1, Point3 &P2) { double area1 = Area2(P, P0, P1); double area2 = Area2(P, P1, P2); double area3 = Area2(P, P2, P0); // cout<= a && x <= b; } inline bool inbox(const P &p) { return p.x >= _min.x && p.x <= _max.x && p.y >= _min.y && p.y <= _max.y && p.z >= _min.z && p.z <= _max.z; } // 判断射线是否在t区间 inline bool hit(P &p1, P &p2) { // 1.0 / direction if (inbox(p1)) return true; if (inbox(p2)) return true; double t0 = -1e9, t1 = 1e9; P dire = p1 - p2; for (int i = 0; i < 3; i++) { if (dcmp(dire.get(i)) == 0) { if (!insig(p1.get(i), _min.get(i), _max.get(i))) return false; } else { double t00 = (_min.get(i) - p1.get(i)) / dire.get(i); double t11 = (_max.get(i) - p1.get(i)) / dire.get(i); if (t00 > t11) swap(t00, t11); t0 = max(t0, t00); t1 = min(t1, t11); } } return t0 <= t1; } } ab[400010]; BVH() { trinum = tot = root = 0; } inline void update(int x) { AABB &a = ab[x]; a._min = P(1e9, 1e9, 1e9); a._max = P(-1e9, -1e9, -1e9); if (ab[x].l) { AABB &b = ab[ab[x].l]; a._min.x = min(a._min.x, b._min.x); a._min.y = min(a._min.y, b._min.y); a._min.z = min(a._min.z, b._min.z); a._max.x = max(a._max.x, b._max.x); a._max.y = max(a._max.y, b._max.y); a._max.z = max(a._max.z, b._max.z); } if (ab[x].r) { AABB &b = ab[ab[x].r]; a._min.x = min(a._min.x, b._min.x); a._min.y = min(a._min.y, b._min.y); a._min.z = min(a._min.z, b._min.z); a._max.x = max(a._max.x, b._max.x); a._max.y = max(a._max.y, b._max.y); a._max.z = max(a._max.z, b._max.z); } } void build(int &x, int l, int r, int k) { x = ++tot; if (l == r) { tri[l].getbox(ab[x]._min, ab[x]._max); // cout< 0) return false; // 交点不在线段 AB 上 P p = A + (B - A) * t; return PointInTri(p, P0, P1, P2); // 判断交点是否在三角形 P0-P1-P2 内 } } inline bool TriSegIntersection(Triangle &t, Point3 &A, Point3 &B) { P P0 = t.p[0], P1 = t.p[1], P2 = t.p[2]; Vector3 n = Cross(P1 - P0, P2 - P0); if (dcmp(Dot(n, B - A)) == 0) return false; // 线段 AB 和平面 P0P1P2 平行或共面 else { double t = Dot(n, P0 - A) / Dot(n, B - A); if (dcmp(t) < 0 || dcmp(t - 1) > 0) return false; // 交点不在线段 AB 上 if (dcmp(t) == 0) t = 0; if (dcmp(t - 1) == 0) t = 1; P p = A + (B - A) * t; return PointInTri(p, P0, P1, P2); // 判断交点是否在三角形 P0-P1-P2 内 } } /* bool TriSegIntersection(Triangle t,Point3 A,Point3 B,int mood) { P P0=t.p[0],P1=t.p[1],P2=t.p[2]; Vector3 n=Cross(P1-P0,P2-P0); if(dcmp(Dot(n,B-A))==0){ if(mood)cout<<"平行"<0){ if(mood)cout<<"交点不在AB上"< fields; // 声明一个字符串向量 string field; while (sin >> field) { if (field == "vertex") { if (cnt == 3) { trinum++; cnt = 0; } sin >> tri[trinum].p[cnt].x >> tri[trinum].p[cnt].y >> tri[trinum].p[cnt].z; cnt++; } } // cout<