00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef LUX_TABRECKDTREEACCEL_H
00024 #define LUX_TABRECKDTREEACCEL_H
00025
00026
00027 #include "lux.h"
00028 #include "primitive.h"
00029 #include "memory.h"
00030
00031 namespace lux
00032 {
00033
00034 struct TaBRecKdAccelNode {
00035
00036 void initLeaf(int *primNums, int np,
00037 Primitive **prims, MemoryArena &arena) {
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047 nPrims = np << 2;
00048 flags |= 3;
00049
00050 if (np == 0)
00051 onePrimitive = NULL;
00052 else if (np == 1)
00053 onePrimitive = prims[primNums[0]];
00054 else {
00055 primitives = (Primitive **)arena.Alloc(np *
00056 sizeof(Primitive **));
00057 for (int i = 0; i < np; ++i)
00058 primitives[i] = prims[primNums[i]];
00059 }
00060 }
00061 void initInterior(int axis, float s) {
00062
00063
00064 split = s;
00065 flags &= ~3;
00066 flags |= axis;
00067 }
00068 float SplitPos() const { return split; }
00069 int nPrimitives() const { return nPrims >> 2; }
00070 int SplitAxis() const { return flags & 3; }
00071 bool IsLeaf() const { return (flags & 3) == 3; }
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082 union {
00083 u_int flags;
00084 float split;
00085 u_int nPrims;
00086 };
00087 union {
00088 u_int aboveChild;
00089 Primitive *onePrimitive;
00090 Primitive **primitives;
00091 };
00092 };
00093
00094 struct TaBRecBoundEdge {
00095
00096 TaBRecBoundEdge() { }
00097 TaBRecBoundEdge(float tt, int pn, bool starting) {
00098 t = tt;
00099 primNum = pn;
00100 type = starting ? START : END;
00101 }
00102 bool operator<(const TaBRecBoundEdge &e) const {
00103 if (t == e.t)
00104 return (int)type < (int)e.type;
00105 else return t < e.t;
00106 }
00107 float t;
00108 int primNum;
00109 enum { START, END } type;
00110 };
00111
00112
00113
00114
00115
00116 struct TaBRecInverseMailboxes {
00117 int indexFirstFree;
00118 Primitive *mailboxes[8];
00119
00120 TaBRecInverseMailboxes() {
00121 indexFirstFree = 0;
00122
00123 Primitive** mb = mailboxes;
00124 *mb++ = NULL;
00125 *mb++ = NULL;
00126 *mb++ = NULL;
00127 *mb++ = NULL;
00128 *mb++ = NULL;
00129 *mb++ = NULL;
00130 *mb++ = NULL;
00131 *mb = NULL;
00132 }
00133
00134 void addChecked(Primitive *p) {
00135 mailboxes[indexFirstFree++] = p;
00136 indexFirstFree &= 0x7;
00137 }
00138
00139 bool alreadyChecked(const Primitive *p) const {
00140 Primitive* const* mb = mailboxes;
00141
00142 if (*mb++ == p)
00143 return true;
00144 if (*mb++ == p)
00145 return true;
00146 if (*mb++ == p)
00147 return true;
00148 if (*mb++ == p)
00149 return true;
00150 if (*mb++ == p)
00151 return true;
00152 if (*mb++ == p)
00153 return true;
00154 if (*mb++ == p)
00155 return true;
00156 if (*mb == p)
00157 return true;
00158
00159 return false;
00160 }
00161 };
00162
00163
00164 class TaBRecKdTreeAccel : public Aggregate {
00165 public:
00166
00167 TaBRecKdTreeAccel(const vector<Primitive* > &p,
00168 int icost, int scost,
00169 float ebonus, int maxp, int maxDepth);
00170 BBox WorldBound() const { return bounds; }
00171 bool CanIntersect() const { return true; }
00172 ~TaBRecKdTreeAccel();
00173 void buildTree(int nodeNum, const BBox &bounds,
00174 const vector<BBox> &primBounds,
00175 int *primNums, int nprims, int depth,
00176 TaBRecBoundEdge *edges[3],
00177 int *prims0, int *prims1, int badRefines = 0);
00178 bool Intersect(const Ray &ray, Intersection *isect) const;
00179 bool IntersectP(const Ray &ray) const;
00180
00181 static Primitive *CreateAccelerator(const vector<Primitive* > &prims, const ParamSet &ps);
00182
00183 private:
00184
00185 BBox bounds;
00186 int isectCost, traversalCost, maxPrims;
00187 float emptyBonus;
00188
00189 u_int nPrims;
00190 Primitive **prims;
00191 TaBRecKdAccelNode *nodes;
00192 int nAllocedNodes, nextFreeNode;
00193
00194 MemoryArena arena;
00195 };
00196
00197 struct TaBRecKdNodeStack {
00198 const TaBRecKdAccelNode *node;
00199 float t;
00200
00201 Point pb;
00202
00203 int prev;
00204 };
00205
00206 }
00207
00208 #endif
00209