| 1 | // Copyright 2009-2021 Intel Corporation | 
| 2 | // SPDX-License-Identifier: Apache-2.0 | 
| 3 |  | 
| 4 | #pragma once | 
| 5 |  | 
| 6 | #include "bvh_node_base.h" | 
| 7 |  | 
| 8 | namespace embree | 
| 9 | { | 
| 10 |   /*! Node with unaligned bounds */ | 
| 11 |   template<typename NodeRef, int N> | 
| 12 |     struct OBBNode_t : public BaseNode_t<NodeRef, N> | 
| 13 |   { | 
| 14 |     using BaseNode_t<NodeRef,N>::children; | 
| 15 |      | 
| 16 |     struct Create | 
| 17 |     { | 
| 18 |       __forceinline NodeRef operator() (const FastAllocator::CachedAllocator& alloc) const | 
| 19 |       { | 
| 20 |         OBBNode_t* node = (OBBNode_t*) alloc.malloc0(bytes: sizeof(OBBNode_t),align: NodeRef::byteNodeAlignment); node->clear(); | 
| 21 |         return NodeRef::encodeNode(node); | 
| 22 |       } | 
| 23 |     }; | 
| 24 |      | 
| 25 |     struct Set | 
| 26 |     { | 
| 27 |       __forceinline void operator() (NodeRef node, size_t i, NodeRef child, const OBBox3fa& bounds) const { | 
| 28 |         node.ungetAABBNode()->setRef(i,child); | 
| 29 |         node.ungetAABBNode()->setBounds(i,bounds); | 
| 30 |       } | 
| 31 |     }; | 
| 32 |      | 
| 33 |     /*! Clears the node. */ | 
| 34 |     __forceinline void clear() | 
| 35 |     { | 
| 36 |       naabb.l.vx = Vec3fa(nan); | 
| 37 |       naabb.l.vy = Vec3fa(nan); | 
| 38 |       naabb.l.vz = Vec3fa(nan); | 
| 39 |       naabb.p    = Vec3fa(nan); | 
| 40 |       BaseNode_t<NodeRef,N>::clear(); | 
| 41 |     } | 
| 42 |      | 
| 43 |     /*! Sets bounding box. */ | 
| 44 |     __forceinline void setBounds(size_t i, const OBBox3fa& b) | 
| 45 |     { | 
| 46 |       assert(i < N); | 
| 47 |        | 
| 48 |       AffineSpace3fa space = b.space; | 
| 49 |       space.p -= b.bounds.lower; | 
| 50 |       space = AffineSpace3fa::scale(s: 1.0f/max(a: Vec3fa(1E-19f),b: b.bounds.upper-b.bounds.lower))*space; | 
| 51 |        | 
| 52 |       naabb.l.vx.x[i] = space.l.vx.x; | 
| 53 |       naabb.l.vx.y[i] = space.l.vx.y; | 
| 54 |       naabb.l.vx.z[i] = space.l.vx.z; | 
| 55 |        | 
| 56 |       naabb.l.vy.x[i] = space.l.vy.x; | 
| 57 |       naabb.l.vy.y[i] = space.l.vy.y; | 
| 58 |       naabb.l.vy.z[i] = space.l.vy.z; | 
| 59 |        | 
| 60 |       naabb.l.vz.x[i] = space.l.vz.x; | 
| 61 |       naabb.l.vz.y[i] = space.l.vz.y; | 
| 62 |       naabb.l.vz.z[i] = space.l.vz.z; | 
| 63 |        | 
| 64 |       naabb.p.x[i] = space.p.x; | 
| 65 |       naabb.p.y[i] = space.p.y; | 
| 66 |       naabb.p.z[i] = space.p.z; | 
| 67 |     } | 
| 68 |      | 
| 69 |     /*! Sets ID of child. */ | 
| 70 |     __forceinline void setRef(size_t i, const NodeRef& ref) { | 
| 71 |       assert(i < N); | 
| 72 |       children[i] = ref; | 
| 73 |     } | 
| 74 |      | 
| 75 |     /*! Returns the extent of the bounds of the ith child */ | 
| 76 |     __forceinline Vec3fa extent(size_t i) const { | 
| 77 |       assert(i<N); | 
| 78 |       const Vec3fa vx(naabb.l.vx.x[i],naabb.l.vx.y[i],naabb.l.vx.z[i]); | 
| 79 |       const Vec3fa vy(naabb.l.vy.x[i],naabb.l.vy.y[i],naabb.l.vy.z[i]); | 
| 80 |       const Vec3fa vz(naabb.l.vz.x[i],naabb.l.vz.y[i],naabb.l.vz.z[i]); | 
| 81 |       return rsqrt(a: vx*vx + vy*vy + vz*vz); | 
| 82 |     } | 
| 83 |      | 
| 84 |     /*! Returns reference to specified child */ | 
| 85 |     __forceinline       NodeRef& child(size_t i)       { assert(i<N); return children[i]; } | 
| 86 |     __forceinline const NodeRef& child(size_t i) const { assert(i<N); return children[i]; } | 
| 87 |      | 
| 88 |     /*! output operator */ | 
| 89 |     friend embree_ostream operator<<(embree_ostream o, const OBBNode_t& n) | 
| 90 |     { | 
| 91 |       o << "UnAABBNode { "  << n.naabb << " } "  << embree_endl; | 
| 92 |       return o; | 
| 93 |     } | 
| 94 |      | 
| 95 |   public: | 
| 96 |     AffineSpace3vf<N> naabb;   //!< non-axis aligned bounding boxes (bounds are [0,1] in specified space) | 
| 97 |   }; | 
| 98 | } | 
| 99 |  |