⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 boundingintervalhierarchy.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
                        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 + -