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

📄 beziermesh.java

📁 Sunflow是一个照片级的渲染系统
💻 JAVA
📖 第 1 页 / 共 2 页
字号:

    public int getNumPrimitives() {
        return patches.length;
    }

    public float getPrimitiveBound(int primID, int i) {
        float[] patch = patches[primID];
        int axis = i >>> 1;
        if ((i & 1) == 0) {
            float min = patch[axis];
            for (int j = axis + 3; j < patch.length; j += 3)
                if (min > patch[j])
                    min = patch[j];
            return min;
        } else {
            float max = patch[axis];
            for (int j = axis + 3; j < patch.length; j += 3)
                if (max < patch[j])
                    max = patch[j];
            return max;
        }
    }

    public void intersectPrimitive(Ray r, int primID, IntersectionState state) {
        // ray patch intersection
        final float[] stack = state.getRobustStack();
        final int STACKSIZE = 64;
        {
            // init patch
            float[] patch = patches[primID];
            for (int i = 0; i < 4 * 4 * 3; i++)
                stack[i] = patch[i];
            stack[48] = Float.POSITIVE_INFINITY; // bbox size
            stack[49] = 0; // umin
            stack[50] = 0; // vmin
            stack[51] = 1; // umax
            stack[52] = 1; // vmax
        }
        int stackpos = 0;
        float orgX = r.ox, invDirX = 1 / r.dx;
        float orgY = r.oy, invDirY = 1 / r.dy;
        float orgZ = r.oz, invDirZ = 1 / r.dz;
        float t1, t2;
        while (stackpos >= 0) {
            float intervalMin = r.getMin();
            float intervalMax = r.getMax();
            // x-axis bbox
            float minx = stack[stackpos + 0];
            float maxx = stack[stackpos + 0];
            for (int j = 1, idx = stackpos + 3; j < 4 * 4; j++, idx += 3) {
                if (minx > stack[idx])
                    minx = stack[idx];
                if (maxx < stack[idx])
                    maxx = stack[idx];
            }
            t1 = (minx - orgX) * invDirX;
            t2 = (maxx - 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) {
                stackpos -= STACKSIZE;
                continue;
            }
            // y-axis bbox
            float miny = stack[stackpos + 1];
            float maxy = stack[stackpos + 1];
            for (int j = 1, idx = stackpos + 4; j < 4 * 4; j++, idx += 3) {
                if (miny > stack[idx])
                    miny = stack[idx];
                if (maxy < stack[idx])
                    maxy = stack[idx];
            }
            t1 = (miny - orgY) * invDirY;
            t2 = (maxy - 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) {
                stackpos -= STACKSIZE;
                continue;
            }
            // z-axis bbox
            float minz = stack[stackpos + 2];
            float maxz = stack[stackpos + 2];
            for (int j = 1, idx = stackpos + 5; j < 4 * 4; j++, idx += 3) {
                if (minz > stack[idx])
                    minz = stack[idx];
                if (maxz < stack[idx])
                    maxz = stack[idx];
            }

            t1 = (minz - orgZ) * invDirZ;
            t2 = (maxz - 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) {
                stackpos -= STACKSIZE;
                continue;
            }
            // intersection was found - keep going
            float size = (maxx - minx) + (maxy - miny) + (maxz - minz);
            if (Float.floatToRawIntBits(stack[stackpos + 48]) == Float.floatToRawIntBits(size)) {
                // L1 norm is 0, we are done
                r.setMax(intervalMin);
                state.setIntersection(primID, stack[stackpos + 49], stack[stackpos + 50]);
                stackpos -= STACKSIZE;
                continue;
            }
            // not small enough yet - subdivide
            // lets pick a subdivision axis first:
            float sizeu = 0;
            float sizev = 0;
            for (int i = 0; i < 3; i++) {
                sizeu += Math.abs(stack[stackpos + (0 * 4 + 3) * 3 + i] - stack[stackpos + i]);
                sizev += Math.abs(stack[stackpos + (3 * 4 + 0) * 3 + i] - stack[stackpos + i]);
            }

            if (sizeu > sizev) {
                // split in U direction
                for (int i = 0; i < 4; i++) {
                    for (int axis = 0; axis < 3; axis++) {
                        // load data
                        float p0 = stack[stackpos + (i * 4 + 0) * 3 + axis];
                        float p1 = stack[stackpos + (i * 4 + 1) * 3 + axis];
                        float p2 = stack[stackpos + (i * 4 + 2) * 3 + axis];
                        float p3 = stack[stackpos + (i * 4 + 3) * 3 + axis];
                        // Split curve in the middle
                        float q0 = p0;
                        float q1 = (p0 + p1) * 0.5f;
                        float q2 = q1 * 0.5f + (p1 + p2) * 0.25f;
                        float r3 = p3;
                        float r2 = (p2 + p3) * 0.5f;
                        float r1 = r2 * 0.5f + (p1 + p2) * 0.25f;
                        float q3 = (q2 + r1) * 0.5f;
                        float r0 = q3;
                        // load new curve data into the stack
                        stack[stackpos + (i * 4 + 0) * 3 + axis] = q0;
                        stack[stackpos + (i * 4 + 1) * 3 + axis] = q1;
                        stack[stackpos + (i * 4 + 2) * 3 + axis] = q2;
                        stack[stackpos + (i * 4 + 3) * 3 + axis] = q3;
                        stack[stackpos + STACKSIZE + (i * 4 + 0) * 3 + axis] = r0;
                        stack[stackpos + STACKSIZE + (i * 4 + 1) * 3 + axis] = r1;
                        stack[stackpos + STACKSIZE + (i * 4 + 2) * 3 + axis] = r2;
                        stack[stackpos + STACKSIZE + (i * 4 + 3) * 3 + axis] = r3;
                    }
                }
                // copy current bbox size
                stack[stackpos + 48] = stack[stackpos + STACKSIZE + 48] = size;
                // finally - split uv ranges
                float umin = stack[stackpos + 49];
                float umax = stack[stackpos + 51];
                stack[stackpos + 49] = umin;
                stack[stackpos + STACKSIZE + 50] = stack[stackpos + 50];
                stack[stackpos + 51] = stack[stackpos + STACKSIZE + 49] = (umin + umax) * 0.5f;
                stack[stackpos + STACKSIZE + 51] = umax;
                stack[stackpos + STACKSIZE + 52] = stack[stackpos + 52];
            } else {
                // split in V direction
                for (int i = 0; i < 4; i++) {
                    for (int axis = 0; axis < 3; axis++) {
                        // load data
                        float p0 = stack[stackpos + (0 * 4 + i) * 3 + axis];
                        float p1 = stack[stackpos + (1 * 4 + i) * 3 + axis];
                        float p2 = stack[stackpos + (2 * 4 + i) * 3 + axis];
                        float p3 = stack[stackpos + (3 * 4 + i) * 3 + axis];
                        // Split curve in the middle
                        float q0 = p0;
                        float q1 = (p0 + p1) * 0.5f;
                        float q2 = q1 * 0.5f + (p1 + p2) * 0.25f;
                        float r3 = p3;
                        float r2 = (p2 + p3) * 0.5f;
                        float r1 = r2 * 0.5f + (p1 + p2) * 0.25f;
                        float q3 = (q2 + r1) * 0.5f;
                        float r0 = q3;
                        // load new curve data into the stack
                        stack[stackpos + (0 * 4 + i) * 3 + axis] = q0;
                        stack[stackpos + (1 * 4 + i) * 3 + axis] = q1;
                        stack[stackpos + (2 * 4 + i) * 3 + axis] = q2;
                        stack[stackpos + (3 * 4 + i) * 3 + axis] = q3;
                        stack[stackpos + STACKSIZE + (0 * 4 + i) * 3 + axis] = r0;
                        stack[stackpos + STACKSIZE + (1 * 4 + i) * 3 + axis] = r1;
                        stack[stackpos + STACKSIZE + (2 * 4 + i) * 3 + axis] = r2;
                        stack[stackpos + STACKSIZE + (3 * 4 + i) * 3 + axis] = r3;
                    }
                }
                // copy current bbox size
                stack[stackpos + 48] = stack[stackpos + STACKSIZE + 48] = size;
                // finally - split uv ranges
                float vmin = stack[stackpos + 50];
                float vmax = stack[stackpos + 52];
                stack[stackpos + STACKSIZE + 49] = stack[stackpos + 49];
                stack[stackpos + 50] = vmin;
                stack[stackpos + 52] = stack[stackpos + STACKSIZE + 50] = (vmin + vmax) * 0.5f;
                stack[stackpos + STACKSIZE + 51] = stack[stackpos + 51];
                stack[stackpos + STACKSIZE + 52] = vmax;
            }
            stackpos += STACKSIZE;
        }
    }

    public void prepareShadingState(ShadingState state) {
        state.init();
        state.getRay().getPoint(state.getPoint());
        Instance parent = state.getInstance();
        float u = state.getU();
        float v = state.getV();
        float[] bu = bernstein(u);
        float[] bdu = bernsteinDeriv(u);
        float[] bv = bernstein(v);
        float[] bdv = bernsteinDeriv(v);
        getPatchPoint(u, v, patches[state.getPrimitiveID()], bu, bv, bdu, bdv, new Point3(), state.getNormal());
        state.getNormal().set(parent.transformNormalObjectToWorld(state.getNormal()));
        state.getNormal().normalize();
        state.getGeoNormal().set(state.getNormal());
        state.getUV().set(u, v);
        state.setShader(parent.getShader(0));
        state.setModifier(parent.getModifier(0));
        // FIXME: use actual derivatives to create basis
        state.setBasis(OrthoNormalBasis.makeFromW(state.getNormal()));
    }

    public PrimitiveList getBakingPrimitives() {
        return null;
    }
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -