📄 boundingintervalhierarchy.java
字号:
tempTree.set(nodeIndex + 2, Float.floatToRawIntBits(Float.POSITIVE_INFINITY));
} else {
// create a node with a right child
// write leaf node
stats.updateInner();
tempTree.set(nodeIndex + 0, (prevAxis << 30) | (nextIndex - 3));
tempTree.set(nodeIndex + 1, Float.floatToRawIntBits(Float.NEGATIVE_INFINITY));
tempTree.set(nodeIndex + 2, Float.floatToRawIntBits(prevClip));
}
// count stats for the unused leaf
depth++;
stats.updateLeaf(depth, 0);
// now we keep going as we are, with a new nodeIndex:
nodeIndex = nextIndex;
}
break;
}
}
// compute index of child nodes
int nextIndex = tempTree.getSize();
// allocate left node
int nl = right - left + 1;
int nr = rightOrig - (right + 1) + 1;
if (nl > 0) {
tempTree.add(0);
tempTree.add(0);
tempTree.add(0);
} else
nextIndex -= 3;
// allocate right node
if (nr > 0) {
tempTree.add(0);
tempTree.add(0);
tempTree.add(0);
}
// write leaf node
stats.updateInner();
tempTree.set(nodeIndex + 0, (axis << 30) | nextIndex);
tempTree.set(nodeIndex + 1, Float.floatToRawIntBits(clipL));
tempTree.set(nodeIndex + 2, Float.floatToRawIntBits(clipR));
// prepare L/R child boxes
float[] gridBoxL = new float[6];
float[] gridBoxR = new float[6];
float[] nodeBoxL = new float[6];
float[] nodeBoxR = new float[6];
for (int i = 0; i < 6; i++) {
gridBoxL[i] = gridBoxR[i] = gridBox[i];
nodeBoxL[i] = nodeBoxR[i] = nodeBox[i];
}
gridBoxL[2 * axis + 1] = gridBoxR[2 * axis] = split;
nodeBoxL[2 * axis + 1] = clipL;
nodeBoxR[2 * axis + 0] = clipR;
// free memory
gridBox = nodeBox = null;
// recurse
if (nl > 0)
subdivide(left, right, tempTree, indices, gridBoxL, nodeBoxL, nextIndex, depth + 1, stats);
else
stats.updateLeaf(depth + 1, 0);
if (nr > 0)
subdivide(right + 1, rightOrig, tempTree, indices, gridBoxR, nodeBoxR, nextIndex + 3, depth + 1, stats);
else
stats.updateLeaf(depth + 1, 0);
}
public void intersect(Ray r, IntersectionState state) {
float intervalMin = r.getMin();
float intervalMax = r.getMax();
float orgX = r.ox;
float dirX = r.dx, invDirX = 1 / dirX;
float t1, t2;
t1 = (bounds.getMinimum().x - orgX) * invDirX;
t2 = (bounds.getMaximum().x - orgX) * invDirX;
if (invDirX > 0) {
if (t1 > intervalMin)
intervalMin = t1;
if (t2 < intervalMax)
intervalMax = t2;
} else {
if (t2 > intervalMin)
intervalMin = t2;
if (t1 < intervalMax)
intervalMax = t1;
}
if (intervalMin > intervalMax)
return;
float orgY = r.oy;
float dirY = r.dy, invDirY = 1 / dirY;
t1 = (bounds.getMinimum().y - orgY) * invDirY;
t2 = (bounds.getMaximum().y - orgY) * invDirY;
if (invDirY > 0) {
if (t1 > intervalMin)
intervalMin = t1;
if (t2 < intervalMax)
intervalMax = t2;
} else {
if (t2 > intervalMin)
intervalMin = t2;
if (t1 < intervalMax)
intervalMax = t1;
}
if (intervalMin > intervalMax)
return;
float orgZ = r.oz;
float dirZ = r.dz, invDirZ = 1 / dirZ;
t1 = (bounds.getMinimum().z - orgZ) * invDirZ;
t2 = (bounds.getMaximum().z - orgZ) * invDirZ;
if (invDirZ > 0) {
if (t1 > intervalMin)
intervalMin = t1;
if (t2 < intervalMax)
intervalMax = t2;
} else {
if (t2 > intervalMin)
intervalMin = t2;
if (t1 < intervalMax)
intervalMax = t1;
}
if (intervalMin > intervalMax)
return;
// compute custom offsets from direction sign bit
int offsetXFront = Float.floatToRawIntBits(dirX) >>> 31;
int offsetYFront = Float.floatToRawIntBits(dirY) >>> 31;
int offsetZFront = Float.floatToRawIntBits(dirZ) >>> 31;
int offsetXBack = offsetXFront ^ 1;
int offsetYBack = offsetYFront ^ 1;
int offsetZBack = offsetZFront ^ 1;
int offsetXFront3 = offsetXFront * 3;
int offsetYFront3 = offsetYFront * 3;
int offsetZFront3 = offsetZFront * 3;
int offsetXBack3 = offsetXBack * 3;
int offsetYBack3 = offsetYBack * 3;
int offsetZBack3 = offsetZBack * 3;
// avoid always adding 1 during the inner loop
offsetXFront++;
offsetYFront++;
offsetZFront++;
offsetXBack++;
offsetYBack++;
offsetZBack++;
IntersectionState.StackNode[] stack = state.getStack();
int stackTop = state.getStackTop();
int stackPos = stackTop;
int node = 0;
while (true) {
pushloop: while (true) {
int tn = tree[node];
int axis = tn & (7 << 29);
int offset = tn & ~(7 << 29);
switch (axis) {
case 0: {
// x axis
float tf = (Float.intBitsToFloat(tree[node + offsetXFront]) - orgX) * invDirX;
float tb = (Float.intBitsToFloat(tree[node + offsetXBack]) - orgX) * invDirX;
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break pushloop;
int back = offset + offsetXBack3;
node = back;
// ray passes through far node only
if (tf < intervalMin) {
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetXFront3; // front
// ray passes through near node only
if (tb > intervalMax) {
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].near = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].far = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
case 1 << 30: {
float tf = (Float.intBitsToFloat(tree[node + offsetYFront]) - orgY) * invDirY;
float tb = (Float.intBitsToFloat(tree[node + offsetYBack]) - orgY) * invDirY;
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break pushloop;
int back = offset + offsetYBack3;
node = back;
// ray passes through far node only
if (tf < intervalMin) {
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetYFront3; // front
// ray passes through near node only
if (tb > intervalMax) {
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].near = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].far = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
case 2 << 30: {
// z axis
float tf = (Float.intBitsToFloat(tree[node + offsetZFront]) - orgZ) * invDirZ;
float tb = (Float.intBitsToFloat(tree[node + offsetZBack]) - orgZ) * invDirZ;
// ray passes between clip zones
if (tf < intervalMin && tb > intervalMax)
break pushloop;
int back = offset + offsetZBack3;
node = back;
// ray passes through far node only
if (tf < intervalMin) {
intervalMin = (tb >= intervalMin) ? tb : intervalMin;
continue;
}
node = offset + offsetZFront3; // front
// ray passes through near node only
if (tb > intervalMax) {
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
// ray passes through both nodes
// push back node
stack[stackPos].node = back;
stack[stackPos].near = (tb >= intervalMin) ? tb : intervalMin;
stack[stackPos].far = intervalMax;
stackPos++;
// update ray interval for front node
intervalMax = (tf <= intervalMax) ? tf : intervalMax;
continue;
}
case 3 << 30: {
// leaf - test some objects
int n = tree[node + 1];
while (n > 0) {
primitives.intersectPrimitive(r, objects[offset], state);
n--;
offset++;
}
break pushloop;
}
case 1 << 29: {
float tf = (Float.intBitsToFloat(tree[node + offsetXFront]) - orgX) * invDirX;
float tb = (Float.intBitsToFloat(tree[node + offsetXBack]) - orgX) * invDirX;
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
if (intervalMin > intervalMax)
break pushloop;
continue;
}
case 3 << 29: {
float tf = (Float.intBitsToFloat(tree[node + offsetYFront]) - orgY) * invDirY;
float tb = (Float.intBitsToFloat(tree[node + offsetYBack]) - orgY) * invDirY;
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
if (intervalMin > intervalMax)
break pushloop;
continue;
}
case 5 << 29: {
float tf = (Float.intBitsToFloat(tree[node + offsetZFront]) - orgZ) * invDirZ;
float tb = (Float.intBitsToFloat(tree[node + offsetZBack]) - orgZ) * invDirZ;
node = offset;
intervalMin = (tf >= intervalMin) ? tf : intervalMin;
intervalMax = (tb <= intervalMax) ? tb : intervalMax;
if (intervalMin > intervalMax)
break pushloop;
continue;
}
default:
return; // should not happen
} // switch
} // traversal loop
do {
// stack is empty?
if (stackPos == stackTop)
return;
// move back up the stack
stackPos--;
intervalMin = stack[stackPos].near;
if (r.getMax() < intervalMin)
continue;
node = stack[stackPos].node;
intervalMax = stack[stackPos].far;
break;
} while (true);
}
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -