Search in sources :

Example 56 with Vector3f

use of org.joml.Vector3f in project lwjgl3-demos by LWJGL.

the class DemoSsboTrianglesStacklessKdTree method createSceneSSBO.

/**
 * Build the kd-tree of the scene and create two SSBOs:
 * <ul>
 * <li>one for the nodes of the kd-tree
 * <li>and another one to hold all the triangles stored in the leaf nodes of the kd-tree
 * </ul>
 */
void createSceneSSBO() {
    /* Build Kd-tree */
    KDTree kdtree = new KDTree();
    List<Triangle> triangles = new ArrayList<Triangle>();
    int trianglesCount = mesh.positions.remaining() / 3 / 3;
    sceneBounds = new Box();
    Vector3f min = new Vector3f(Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE);
    Vector3f max = new Vector3f(-Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE);
    sceneBounds.min = min;
    sceneBounds.max = max;
    for (int i = 0; i < trianglesCount; i++) {
        Triangle t = new Triangle();
        t.v0 = new Vector3f(mesh.positions.get(i * 3 * 3 + 0), mesh.positions.get(i * 3 * 3 + 1), mesh.positions.get(i * 3 * 3 + 2));
        t.v1 = new Vector3f(mesh.positions.get(i * 3 * 3 + 3), mesh.positions.get(i * 3 * 3 + 4), mesh.positions.get(i * 3 * 3 + 5));
        t.v2 = new Vector3f(mesh.positions.get(i * 3 * 3 + 6), mesh.positions.get(i * 3 * 3 + 7), mesh.positions.get(i * 3 * 3 + 8));
        triangles.add(t);
        min.min(t.v0).min(t.v1).min(t.v2);
        max.max(t.v0).max(t.v1).max(t.v2);
    }
    kdtree.buildTree(triangles, sceneBounds);
    DynamicByteBuffer nodesBuffer = new DynamicByteBuffer();
    DynamicByteBuffer trianglesBuffer = new DynamicByteBuffer();
    kdTreeToBuffers(kdtree, nodesBuffer, trianglesBuffer);
    nodesBuffer.flip();
    trianglesBuffer.flip();
    this.nodesSsbo = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, nodesSsbo);
    glBufferData(GL_ARRAY_BUFFER, nodesBuffer.bb, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    this.trianglesSsbo = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, trianglesSsbo);
    glBufferData(GL_ARRAY_BUFFER, trianglesBuffer.bb, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Also used : KDTree(org.lwjgl.demo.opengl.util.KDTree) Vector3f(org.joml.Vector3f) Triangle(org.lwjgl.demo.opengl.util.KDTree.Triangle) ArrayList(java.util.ArrayList) DynamicByteBuffer(org.lwjgl.demo.opengl.util.DynamicByteBuffer) Box(org.lwjgl.demo.opengl.util.KDTree.Box)

Example 57 with Vector3f

use of org.joml.Vector3f in project lwjgl3-demos by LWJGL.

the class HybridDemoSsbo method createSceneSSBO.

/**
 * Create a Shader Storage Buffer Object which will hold our boxes to be
 * read by our Compute Shader.
 */
private void createSceneSSBO() {
    this.ssbo = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, ssbo);
    ByteBuffer ssboData = BufferUtils.createByteBuffer(4 * (4 + 4) * boxes.length / 2);
    FloatBuffer fv = ssboData.asFloatBuffer();
    for (int i = 0; i < boxes.length; i += 2) {
        Vector3f min = boxes[i];
        Vector3f max = boxes[i + 1];
        /*
			 * NOTE: We need to write vec4 here, because SSBOs have specific
			 * alignment requirements for struct members (vec3 is always treated
			 * as vec4 in memory!)
			 * 
			 * See:
			 * "https://www.safaribooksonline.com/library/view/opengl-programming-guide/9780132748445/app09lev1sec3.html"
			 */
        fv.put(min.x).put(min.y).put(min.z).put(0.0f);
        fv.put(max.x).put(max.y).put(max.z).put(0.0f);
    }
    glBufferData(GL_ARRAY_BUFFER, ssboData, GL_STATIC_DRAW);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
}
Also used : Vector3f(org.joml.Vector3f) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 58 with Vector3f

use of org.joml.Vector3f in project lwjgl3-demos by LWJGL.

the class HybridDemoSsboInstancing method createSceneVao.

/**
 * Creates a VAO for the scene.
 */
private void createSceneVao() {
    int vao = glGenVertexArrays();
    /* Create vertex data */
    int vbo = glGenBuffers();
    glBindVertexArray(vao);
    glBindBuffer(GL_ARRAY_BUFFER, vbo);
    ByteBuffer bb = BufferUtils.createByteBuffer(4 * (3 + 3) * 6 * 6);
    FloatBuffer fv = bb.asFloatBuffer();
    DemoUtils.triangulateUnitBox(fv);
    glBufferData(GL_ARRAY_BUFFER, bb, GL_STATIC_DRAW);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 4 * (3 + 3), 0L);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 3, GL_FLOAT, false, 4 * (3 + 3), 4 * 3);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    /* Create per instance data (position and size of box) */
    int ivbo = glGenBuffers();
    glBindBuffer(GL_ARRAY_BUFFER, ivbo);
    bb = BufferUtils.createByteBuffer(4 * (3 + 3) * boxes.length);
    fv = bb.asFloatBuffer();
    for (int i = 0; i < boxes.length; i += 2) {
        Vector3f min = boxes[i];
        Vector3f max = boxes[i + 1];
        fv.put((max.x + min.x) / 2.0f).put((max.y + min.y) / 2.0f).put((max.z + min.z) / 2.0f);
        fv.put((max.x - min.x) / 2.0f).put((max.y - min.y) / 2.0f).put((max.z - min.z) / 2.0f);
    }
    glBufferData(GL_ARRAY_BUFFER, bb, GL_STATIC_DRAW);
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, false, 4 * (3 + 3), 0L);
    glVertexAttribDivisor(2, 1);
    glEnableVertexAttribArray(3);
    glVertexAttribPointer(3, 3, GL_FLOAT, false, 4 * (3 + 3), 4 * 3);
    glVertexAttribDivisor(3, 1);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);
    this.vaoScene = vao;
}
Also used : Vector3f(org.joml.Vector3f) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 59 with Vector3f

use of org.joml.Vector3f in project lwjgl3-demos by LWJGL.

the class HybridDemoSsboInstancing45 method createSceneVao.

/**
 * Creates a VAO for the scene.
 */
private void createSceneVao() {
    int vao = glCreateVertexArrays();
    /* Create vertex data */
    int vbo = glCreateBuffers();
    ByteBuffer bb = BufferUtils.createByteBuffer(4 * (3 + 3) * 6 * 6);
    FloatBuffer fv = bb.asFloatBuffer();
    DemoUtils.triangulateUnitBox(fv);
    glNamedBufferData(vbo, bb, GL_STATIC_DRAW);
    glEnableVertexArrayAttrib(vao, 0);
    glVertexArrayAttribFormat(vao, 0, 3, GL_FLOAT, false, 0);
    glVertexArrayVertexBuffer(vao, 0, vbo, 0L, 4 * (3 + 3));
    glVertexArrayAttribBinding(vao, 0, 0);
    glEnableVertexArrayAttrib(vao, 1);
    glVertexArrayAttribFormat(vao, 1, 3, GL_FLOAT, false, 0);
    glVertexArrayVertexBuffer(vao, 1, vbo, 4 * 3, 4 * (3 + 3));
    glVertexArrayAttribBinding(vao, 1, 1);
    /* Create per instance data (position and size of box) */
    int ivbo = glCreateBuffers();
    bb = BufferUtils.createByteBuffer(4 * (3 + 3) * boxes.length);
    fv = bb.asFloatBuffer();
    for (int i = 0; i < boxes.length; i += 2) {
        Vector3f min = boxes[i];
        Vector3f max = boxes[i + 1];
        fv.put((max.x + min.x) / 2.0f).put((max.y + min.y) / 2.0f).put((max.z + min.z) / 2.0f);
        fv.put((max.x - min.x) / 2.0f).put((max.y - min.y) / 2.0f).put((max.z - min.z) / 2.0f);
    }
    glNamedBufferData(ivbo, bb, GL_STATIC_DRAW);
    glEnableVertexArrayAttrib(vao, 2);
    glVertexArrayAttribFormat(vao, 2, 3, GL_FLOAT, false, 0);
    glVertexArrayVertexBuffer(vao, 2, ivbo, 0L, 4 * (3 + 3));
    glVertexArrayAttribBinding(vao, 2, 2);
    glVertexArrayBindingDivisor(vao, 2, 1);
    glEnableVertexArrayAttrib(vao, 3);
    glVertexArrayAttribFormat(vao, 3, 3, GL_FLOAT, false, 0);
    glVertexArrayVertexBuffer(vao, 3, ivbo, 4 * 3, 4 * (3 + 3));
    glVertexArrayAttribBinding(vao, 3, 3);
    glVertexArrayBindingDivisor(vao, 3, 1);
    this.vaoScene = vao;
}
Also used : Vector3f(org.joml.Vector3f) FloatBuffer(java.nio.FloatBuffer) ByteBuffer(java.nio.ByteBuffer)

Example 60 with Vector3f

use of org.joml.Vector3f in project lwjgl3-demos by LWJGL.

the class KDTree method findSplitPlane.

// find optimal split
private float findSplitPlane(Node node) {
    if (node == null) {
        return Float.POSITIVE_INFINITY;
    }
    Split strategy = mSplitStrategy;
    // use arithmetic average
    if (strategy.equals(Split.MEAN)) {
        float avg = 0.0f;
        for (int i = 0; i < node.triangles.size(); i++) {
            Box bounds = node.triangles.get(i).getBounds();
            avg += (Vector3f_get(bounds.min, node.splitAxis.dim) + Vector3f_get(bounds.max, node.splitAxis.dim)) * 0.5f;
        }
        avg /= node.triangles.size();
        return avg;
    }
    // use median
    if (strategy.equals(Split.MEDIAN)) {
        List<Float> vecIntervalMeans = new ArrayList<Float>(node.triangles.size());
        for (int i = 0; i < node.triangles.size(); i++) {
            Box bounds = node.triangles.get(i).getBounds();
            vecIntervalMeans.add(Float.valueOf(0.5f * (Vector3f_get(bounds.min, node.splitAxis.dim) + Vector3f_get(bounds.max, node.splitAxis.dim))));
        }
        Collections.sort(vecIntervalMeans);
        return vecIntervalMeans.get(vecIntervalMeans.size() / 2).floatValue();
    }
    // use surface area heuristic
    if (strategy.equals(Split.SAH)) {
        Box bb = node.boundingBox;
        int nPrims = node.triangles.size();
        // do a complete scan
        if (nPrims > mSahThreshold) {
            // sampleing
            Vector3f costvector = new Vector3f(bb.max).sub(bb.min);
            int ax = Vector3f_maxDimension(costvector);
            float box_width = Vector3f_get(bb.max, ax) - Vector3f_get(bb.min, ax);
            if (box_width <= EPSILON) {
                node.splitAxis = Axis.NO_AXIS;
                return Float.POSITIVE_INFINITY;
            }
            float inv_box_width = 1.0f / box_width;
            if (box_width < 0.0f) {
                throw new IllegalStateException("!!! KDTree.findSplitPlane: invalid box width < 0");
            }
            // triangle counts for histogram
            int[] p = new int[mSahRes];
            int[] h = new int[mSahRes];
            int[] p_rtl = new int[mSahRes];
            float triangleLeftEdge;
            // build histogram
            for (int i = 0; i < nPrims; i++) {
                Box bounds = node.triangles.get(i).getBounds();
                triangleLeftEdge = Math.min(Vector3f_get(bb.max, ax), Math.max(Vector3f_get(bb.min, ax), (Vector3f_get(bounds.min, ax) + Vector3f_get(bounds.max, ax)) * 0.5f)) - Vector3f_get(bb.min, ax);
                if (!bb.intersectsWithBox(bounds)) {
                    throw new IllegalStateException("!!! KDTree.findSplitPlane: no intersection of boxes!");
                }
                if (triangleLeftEdge < 0.0 || inv_box_width * triangleLeftEdge > 1.0f + EPSILON) {
                    throw new IllegalStateException("!!! KDTree.findSplitPlane: triangleLeftEdge invalid : " + triangleLeftEdge + ", " + (inv_box_width * triangleLeftEdge));
                }
                float hf = inv_box_width * (triangleLeftEdge - EPSILON) * (mSahRes - 1.0f);
                h[(int) hf] += 1;
            }
            // copy p for right-to-left lookup
            for (int i = 0; i < mSahRes - 1; i++) {
                p[i] = h[i + 1];
            }
            for (int i = 0; i < mSahRes - 1; i++) {
                p_rtl[i] = p[i + 1];
            }
            p_rtl[mSahRes - 1] = 0;
            // convert p and p_rtl into cumulative quantities
            for (int i = 1; i < mSahRes; i++) {
                p[i] += p[i - 1];
            }
            for (int i = mSahRes - 2; i >= 0; i--) {
                p_rtl[i] += p_rtl[i + 1];
            }
            // splitting costs
            float[] costs = new float[mSahRes - 1];
            // determine costs
            for (int i = 0; i < mSahRes - 1; i++) {
                costs[i] = mSahTrvCosts + mSahIntCosts * ((i + 1) * p[i] + (mSahRes - i - 1) * p_rtl[i]) / mSahRes;
            }
            int minid = 0;
            float minval = costs[0];
            // find minimum
            for (int i = 0; i < mSahRes - 1; i++) {
                if (minval > costs[i]) {
                    minval = costs[i];
                    minid = i;
                }
            }
            float splitPosition = ((minid + 1.0f) / mSahRes) * box_width + Vector3f_get(bb.min, ax);
            node.splitAxis = Axis.values()[ax];
            return splitPosition;
        }
        // complete scan
        Vector3f costvector = new Vector3f(bb.max).sub(bb.min);
        int ax = Vector3f_maxDimension(costvector);
        float box_width = Vector3f_get(costvector, ax);
        // only split if it makes sense
        if (box_width <= EPSILON) {
            node.splitAxis = Axis.NO_AXIS;
            return Float.POSITIVE_INFINITY;
        }
        float inv_box_width = 1.0f / box_width;
        if (box_width <= EPSILON) {
            throw new IllegalStateException("!!! KDTree.findSplitPlane: box to small");
        }
        List<IntervalBoundary> intervals = new ArrayList<IntervalBoundary>();
        // find splitpositions
        for (int i = 0; i < nPrims; i++) {
            Box b = node.triangles.get(i).getBounds();
            if (!bb.intersectsWithBox(b)) {
                throw new IllegalStateException("!!! KDTree.findSplitPlane: no intersection of boxes");
            }
            intervals.add(new IntervalBoundary(BoundaryType.LOWER_BOUND, Vector3f_get(b.min, ax)));
            intervals.add(new IntervalBoundary(BoundaryType.UPPER_BOUND, Vector3f_get(b.max, ax)));
        }
        Collections.sort(intervals, new Comparator<IntervalBoundary>() {

            @Override
            public int compare(IntervalBoundary sib1, IntervalBoundary sib2) {
                return sib1.compareTo(sib2);
            }
        });
        int done_intervals = 0;
        int open_intervals = 0;
        float alpha;
        // find minimum cost
        int minid = 0;
        float mincost = Float.MAX_VALUE;
        for (int i = 0; i < intervals.size(); i++) {
            if (intervals.get(i).type.equals(BoundaryType.UPPER_BOUND)) {
                open_intervals--;
                done_intervals++;
            }
            alpha = (intervals.get(i).pos - Vector3f_get(bb.min, ax)) * inv_box_width;
            float cost = mSahTrvCosts + mSahIntCosts * ((done_intervals + open_intervals) * alpha + (nPrims - done_intervals) * (1.0f - alpha));
            if (cost < mincost) {
                minid = i;
                mincost = cost;
            }
            if (intervals.get(i).type.equals(BoundaryType.LOWER_BOUND)) {
                open_intervals++;
            }
        }
        float splitPlane = intervals.get(minid).pos;
        // no cuts at the boundaries
        if (splitPlane == Vector3f_get(bb.min, ax) || splitPlane == Vector3f_get(bb.max, ax)) {
            node.splitAxis = Axis.NO_AXIS;
            return Float.POSITIVE_INFINITY;
        }
        node.splitAxis = Axis.values()[ax];
        return intervals.get(minid).pos;
    }
    throw new IllegalStateException("!!! KDTree.findSplitPlane: invalid value");
}
Also used : ArrayList(java.util.ArrayList) Vector3f(org.joml.Vector3f)

Aggregations

Vector3f (org.joml.Vector3f)60 ByteBuffer (java.nio.ByteBuffer)14 FloatBuffer (java.nio.FloatBuffer)12 Matrix4f (org.joml.Matrix4f)10 Vector3d (org.joml.Vector3d)7 Vector4f (org.joml.Vector4f)7 ArrayList (java.util.ArrayList)6 Texture2D (io.xol.chunkstories.api.rendering.textures.Texture2D)5 Location (io.xol.chunkstories.api.Location)4 Light (io.xol.chunkstories.api.rendering.lightning.Light)4 RenderingInterface (io.xol.chunkstories.api.rendering.RenderingInterface)3 Shader (io.xol.chunkstories.api.rendering.shader.Shader)3 BufferedReader (java.io.BufferedReader)3 IOException (java.io.IOException)3 ItemVoxel (io.xol.chunkstories.api.item.ItemVoxel)2 Voxel (io.xol.chunkstories.api.voxel.Voxel)2 CellData (io.xol.chunkstories.api.world.cell.CellData)2 DummyCell (io.xol.chunkstories.api.world.cell.DummyCell)2 File (java.io.File)2 InputStreamReader (java.io.InputStreamReader)2