Search in sources :

Example 1 with RegionMesh

use of io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh in project chunkstories by Hugobros3.

the class FarTerrainMeshRenderer method drawTerrainBits.

private int drawTerrainBits(RenderingInterface renderingContext, ReadyVoxelMeshesMask mask, Shader terrainShader) {
    // Starts asynch regeneration
    if (farTerrainUpdatesToTakeIntoAccount.get() > 0 && (System.currentTimeMillis() - this.lastTerrainUpdateTiming) > this.timeToWaitBetweenTerrainUpdates) {
        if (this.isTerrainUpdateRunning.compareAndSet(false, true))
            this.startAsynchSummaryRegeneration(renderingContext.getCamera());
    }
    // Setups stuff
    renderingContext.setCullingMode(CullingMode.COUNTERCLOCKWISE);
    renderingContext.setDepthTestMode(DepthTestMode.LESS_OR_EQUAL);
    // Camera is of position
    CameraInterface camera = renderingContext.getCamera();
    int camRX = (int) (camera.getCameraPosition().x() / 256);
    int camRZ = (int) (camera.getCameraPosition().z() / 256);
    int wrapRegionsDistance = world.getSizeInChunks() / 2;
    int worldSizeInRegions = world.getSizeInChunks() / 8;
    int cameraChunkX = (int) (camera.getCameraPosition().x() / 32);
    int cameraChunkZ = (int) (camera.getCameraPosition().z() / 32);
    // Update their displayed position to reflect where the camera is
    for (RegionMesh mesh : renderedRegions) {
        mesh.regionDisplayedX = mesh.regionSummary.getRegionX();
        mesh.regionDisplayedZ = mesh.regionSummary.getRegionZ();
        // We wrap the chunks if they are too far
        if (mesh.regionSummary.getRegionX() * 8 - cameraChunkX > wrapRegionsDistance)
            mesh.regionDisplayedX += -worldSizeInRegions;
        if (mesh.regionSummary.getRegionX() * 8 - cameraChunkX < -wrapRegionsDistance)
            mesh.regionDisplayedX += worldSizeInRegions;
        if (mesh.regionSummary.getRegionZ() * 8 - cameraChunkZ > wrapRegionsDistance)
            mesh.regionDisplayedZ += -worldSizeInRegions;
        if (mesh.regionSummary.getRegionZ() * 8 - cameraChunkZ < -wrapRegionsDistance)
            mesh.regionDisplayedZ += worldSizeInRegions;
    // System.out.println(mesh.regionDisplayedX + " : " + cameraChunkX);
    }
    // Sort to draw near first
    // µ-opt
    // List<FarTerrainBaker.RegionMesh> regionsMeshesToRenderSorted = new ArrayList<FarTerrainBaker.RegionMesh>(renderedRegions);
    regionsMeshesToRenderSorted.clear();
    regionsMeshesToRenderSorted.addAll(renderedRegions);
    regionsMeshesToRenderSorted.sort(new Comparator<FarTerrainBaker.RegionMesh>() {

        @Override
        public int compare(FarTerrainBaker.RegionMesh a, FarTerrainBaker.RegionMesh b) {
            int distanceA = Math.abs(a.regionDisplayedX - camRX) + Math.abs(a.regionDisplayedZ - camRZ);
            int distanceB = Math.abs(b.regionDisplayedX - camRX) + Math.abs(b.regionDisplayedZ - camRZ);
            return distanceA - distanceB;
        }
    });
    // µ-opt
    /*List<Integer> temp = new ArrayList<Integer>();
		List<Integer> temp2 = new ArrayList<Integer>();*/
    temp.clear();
    temp2.clear();
    int bitsDrew = 0;
    CollisionBox collisionBoxCheck = new CollisionBox(0, 0, 0, 0, 0, 0);
    for (FarTerrainBaker.RegionMesh regionMesh : regionsMeshesToRenderSorted) {
        // Frustrum checks (assuming maxHeight of 1024 blocks)
        // TODO do a simple max() and improve accuracy
        float height = 1024f;
        // Early-out
        if (!renderingContext.getCamera().isBoxInFrustrum(new CollisionBox(regionMesh.regionDisplayedX * 256, 0, regionMesh.regionDisplayedZ * 256, 256, height, 256)))
            continue;
        for (int i = 0; i < 8; i++) for (int j = 0; j < 8; j++) {
            int delta = regionMesh.regionSummary.max[i][j] - regionMesh.regionSummary.min[i][j];
            collisionBoxCheck.xpos = (regionMesh.regionDisplayedX * 8 + i) * 32;
            collisionBoxCheck.ypos = regionMesh.regionSummary.min[i][j];
            collisionBoxCheck.zpos = (regionMesh.regionDisplayedZ * 8 + j) * 32;
            collisionBoxCheck.xw = 32;
            collisionBoxCheck.h = delta + 1;
            collisionBoxCheck.zw = 32;
            if (renderingContext.getCamera().isBoxInFrustrum(collisionBoxCheck)) // if (renderingContext.getCamera().isBoxInFrustrum(new CollisionBox((regionMesh.regionDisplayedX * 8 + i) * 32, regionMesh.regionSummary.min[i][j], (regionMesh.regionDisplayedZ * 8 + j) * 32, 32, delta + 1, 32)))
            {
                if (mask != null) {
                    if (mask.shouldMaskSlab(regionMesh.regionDisplayedX * 8 + i, regionMesh.regionDisplayedZ * 8 + j, regionMesh.regionSummary.min[i][j], regionMesh.regionSummary.max[i][j]))
                        continue;
                }
                temp.add(regionMesh.vertexSectionsOffsets[i][j]);
                temp2.add(regionMesh.vertexSectionsSizes[i][j]);
            }
        }
        if (temp.size() == 0)
            continue;
        HeightmapImplementation regionSummaryData = regionMesh.regionSummary;
        // Skip unloaded regions immediately
        if (regionSummaryData.isUnloaded())
            continue;
        renderingContext.bindArrayTexture("heights", worldRenderer.getSummariesTexturesHolder().getHeightsArrayTexture());
        renderingContext.bindArrayTexture("topVoxels", worldRenderer.getSummariesTexturesHolder().getTopVoxelsArrayTexture());
        renderingContext.bindTexture1D("blocksTexturesSummary", getBlocksTexturesSummary());
        int index = worldRenderer.getSummariesTexturesHolder().getSummaryIndex(regionSummaryData.getRegionX(), regionSummaryData.getRegionZ());
        if (index == -1) {
            // System.out.println("index == -1");
            continue;
        }
        // System.out.println("index:"+index);
        terrainShader.setUniform1i("arrayIndex", index);
        /*renderingContext.bindTexture2D("groundTexture", regionSummaryData.voxelTypesTexture);
			regionSummaryData.voxelTypesTexture.setTextureWrapping(false);
			regionSummaryData.voxelTypesTexture.setLinearFiltering(false);
			
			renderingContext.bindTexture2D("heightMap", regionSummaryData.heightsTexture);
			regionSummaryData.heightsTexture.setTextureWrapping(false);
			regionSummaryData.heightsTexture.setLinearFiltering(false);*/
        // Actual region position
        terrainShader.setUniform2f("regionPosition", regionSummaryData.getRegionX(), regionSummaryData.getRegionZ());
        // Displayed position
        terrainShader.setUniform2f("visualOffset", regionMesh.regionDisplayedX * 256, regionMesh.regionDisplayedZ * 256);
        // Checks this regionMesh instance has it's stuff uploaded already
        if (!regionMesh.verticesObject.isDataPresent())
            continue;
        // else
        // System.out.println("warning");
        int stride = 4 * 2 + 4 + 0 * 4;
        int vertices2draw = (int) (regionMesh.verticesObject.getVramUsage() / stride);
        renderingContext.bindAttribute("vertexIn", regionMesh.verticesObject.asAttributeSource(VertexFormat.SHORT, 3, stride, 0L));
        renderingContext.bindAttribute("normalIn", regionMesh.verticesObject.asAttributeSource(VertexFormat.UBYTE, 4, stride, 8L));
        bitsDrew += vertices2draw;
        int[] theStuff = new int[temp.size() * 2];
        for (int i = 0; i < temp.size(); i++) {
            theStuff[i * 2] = temp.get(i);
            theStuff[i * 2 + 1] = temp2.get(i);
        }
        temp.clear();
        temp2.clear();
        renderingContext.drawMany(Primitive.TRIANGLE, theStuff);
    }
    return bitsDrew;
}
Also used : RegionMesh(io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh) HeightmapImplementation(io.xol.chunkstories.world.summary.HeightmapImplementation) RegionMesh(io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh) CameraInterface(io.xol.chunkstories.api.rendering.CameraInterface) CollisionBox(io.xol.chunkstories.api.physics.CollisionBox)

Example 2 with RegionMesh

use of io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh in project chunkstories by Hugobros3.

the class FarTerrainMeshRenderer method startAsynchSummaryRegeneration.

private void startAsynchSummaryRegeneration(CameraInterface camera) {
    cameraChunkX = (int) (camera.getCameraPosition().x() / 32);
    cameraChunkZ = (int) (camera.getCameraPosition().z() / 32);
    Thread asynchGenerateThread = new Thread() {

        @Override
        public void run() {
            int tookIntoAccount = farTerrainUpdatesToTakeIntoAccount.get();
            Thread.currentThread().setName("Far terrain rebuilder thread");
            Thread.currentThread().setPriority(Constants.TERRAIN_RENDERER_THREAD_PRIORITY);
            FarTerrainBaker baker = new FarTerrainBaker(regionMeshBuffer, world, cameraChunkX, cameraChunkZ);
            List<RegionMesh> previousMeshes = renderedRegions;
            renderedRegions = baker.generateArround();
            if (previousMeshes != null) {
                for (RegionMesh rm : previousMeshes) {
                    rm.delete();
                }
            }
            farTerrainUpdatesToTakeIntoAccount.addAndGet(-tookIntoAccount);
            lastTerrainUpdateTiming = System.currentTimeMillis();
            isTerrainUpdateRunning.set(false);
        }
    };
    asynchGenerateThread.start();
}
Also used : RegionMesh(io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh)

Aggregations

RegionMesh (io.xol.chunkstories.renderer.terrain.FarTerrainBaker.RegionMesh)2 CollisionBox (io.xol.chunkstories.api.physics.CollisionBox)1 CameraInterface (io.xol.chunkstories.api.rendering.CameraInterface)1 HeightmapImplementation (io.xol.chunkstories.world.summary.HeightmapImplementation)1