Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(JOML): migrate world generation #13

Merged
merged 4 commits into from
Dec 26, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion module.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"id": "Caves",
"version": "1.1.0",
"version": "1.1.0-SNAPSHOT",
"author": "Josharias",
"displayName": "Caves",
"description": "Adds configurable caves to the world",
Expand Down
11 changes: 7 additions & 4 deletions src/main/java/org/terasology/caves/CaveFacet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,23 @@
*/
package org.terasology.caves;

import org.terasology.math.Region3i;
import org.joml.Vector3ic;
import org.terasology.math.geom.Vector3i;
import org.terasology.world.block.BlockRegion;
import org.terasology.world.generation.Border3D;
import org.terasology.world.generation.facets.base.BaseBooleanFieldFacet3D;

import java.util.Vector;

public class CaveFacet extends BaseBooleanFieldFacet3D {
public CaveFacet(Region3i targetRegion, Border3D border) {
public CaveFacet(BlockRegion targetRegion, Border3D border) {
super(targetRegion, border);
}

/**
* The index of the given position in arrays corresponding to the region this facet covers.
*/
public int getWorldIndex(Vector3i pos) {
return getWorldIndex(pos.x, pos.y, pos.z);
public int getWorldIndex(Vector3ic pos) {
return getWorldIndex(pos.x(), pos.y(), pos.z());
}
}
9 changes: 4 additions & 5 deletions src/main/java/org/terasology/caves/CaveFacetProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,7 @@
// SPDX-License-Identifier: Apache-2.0
package org.terasology.caves;

import org.terasology.math.geom.Vector3f;
import org.terasology.math.geom.Vector3i;
import org.joml.Vector3ic;
import org.terasology.utilities.procedural.BrownianNoise;
import org.terasology.utilities.procedural.SimplexNoise;
import org.terasology.utilities.procedural.SubSampledNoise;
Expand Down Expand Up @@ -32,7 +31,7 @@ public class CaveFacetProvider implements FacetProviderPlugin {
public void setSeed(long seed) {
for(int i=0; i<2; i++) {
BrownianNoise baseNoise = new BrownianNoise(new SimplexNoise(seed + 2 + i), 4);
caveNoise[i] = new SubSampledNoise(baseNoise, new Vector3f(0.006f, 0.006f, 0.006f), 4);
caveNoise[i] = new SubSampledNoise(baseNoise, new org.joml.Vector3f(0.006f, 0.006f, 0.006f), 4);
}
}

Expand All @@ -44,8 +43,8 @@ public void process(GeneratingRegion region) {
// get noise in batch for performance reasons. Getting it by individual position takes 10 times as long
float[][] caveNoiseValues = new float[][]{caveNoise[0].noise(facet.getWorldRegion()),caveNoise[1].noise(facet.getWorldRegion())};

for (Vector3i pos : facet.getWorldRegion()) {
float depth = elevationFacet.getWorld(pos.x, pos.z) - pos.y;
for (Vector3ic pos : facet.getWorldRegion()) {
float depth = elevationFacet.getWorld(pos.x(), pos.z()) - pos.y();
float frequencyReduction = (float) Math.max(0, 0.3 - Math.max(depth, 0) / 400); //0: no reduction, 0.7: pretty much no caves. Also somewhat increases the tendency of caves to loop rather than continuing indefinitely.
int i = facet.getWorldIndex(pos);
float noiseValue = (float) Math.hypot(caveNoiseValues[0][i], caveNoiseValues[1][i]+frequencyReduction);
Expand Down
6 changes: 3 additions & 3 deletions src/main/java/org/terasology/caves/CaveLocationFacet.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,22 +15,22 @@
*/
package org.terasology.caves;

import org.terasology.math.Region3i;
import org.terasology.world.block.BlockRegion;
import org.terasology.world.generation.Border3D;
import org.terasology.world.generation.Facet;
import org.terasology.world.generation.facets.base.BaseObjectFacet2D;

/**
* This {@link Facet} adds to the {@link CaveFacet} by indicating the Y (height) value throughout the
* {@link Region3i} for both the floor and ceiling of the caves in the {@code CaveFacet}, if present.
* {@link BlockRegion} for both the floor and ceiling of the caves in the {@code CaveFacet}, if present.
* If no Cave floor or ceiling is present then {@link Float#NaN} will be the value for that location.
*
* <p><em>Usage notes:</em> The value of the floor / ceiling is the height of the last relevant solid block.
* So in order to place something "on the floor" / "on the ceiling" of the cave you should place it at
* {@code caveLocation.floor + 1} / {@code caveLocation.ceiling - 1}</p>
*/
public class CaveLocationFacet extends BaseObjectFacet2D<CaveLocation[]> {
public CaveLocationFacet(Region3i targetRegion, Border3D border) {
public CaveLocationFacet(BlockRegion targetRegion, Border3D border) {
super(targetRegion, border, CaveLocation[].class);
}
}
4 changes: 2 additions & 2 deletions src/main/java/org/terasology/caves/CaveLocationProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
*/
package org.terasology.caves;

import org.terasology.math.Region3i;
import org.terasology.world.block.BlockRegion;
import org.terasology.world.generation.Facet;
import org.terasology.world.generation.FacetProviderPlugin;
import org.terasology.world.generation.GeneratingRegion;
Expand All @@ -42,7 +42,7 @@ public void process(GeneratingRegion region) {
CaveLocationFacet locationFacet =
new CaveLocationFacet(region.getRegion(), region.getBorderForFacet(CaveLocationFacet.class));

Region3i worldRegion = caveFacet.getWorldRegion();
BlockRegion worldRegion = caveFacet.getWorldRegion();
for (int x = worldRegion.minX(); x <= worldRegion.maxX(); ++x) {
for (int z = worldRegion.minZ(); z <= worldRegion.maxZ(); ++z) {
boolean insideCave = false;
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/terasology/caves/CaveObjectFacet.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package org.terasology.caves;

import org.terasology.math.Region3i;
import org.terasology.world.block.BlockRegion;
import org.terasology.world.generation.Border3D;
import org.terasology.world.generation.facets.base.SparseObjectFacet3D;

Expand All @@ -24,7 +25,7 @@
*/
public class CaveObjectFacet extends SparseObjectFacet3D<CaveObjectType> {

public CaveObjectFacet(Region3i targetRegion, Border3D border) {
public CaveObjectFacet(BlockRegion targetRegion, Border3D border) {
super(targetRegion, border);
}
}
4 changes: 2 additions & 2 deletions src/main/java/org/terasology/caves/CaveObjectProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,11 @@
package org.terasology.caves;

import org.terasology.entitySystem.Component;
import org.terasology.math.Region3i;
import org.terasology.math.TeraMath;
import org.terasology.nui.properties.Range;
import org.terasology.utilities.procedural.Noise;
import org.terasology.utilities.procedural.WhiteNoise;
import org.terasology.world.block.BlockRegion;
import org.terasology.world.generation.ConfigurableFacetProvider;
import org.terasology.world.generation.Facet;
import org.terasology.world.generation.FacetProviderPlugin;
Expand Down Expand Up @@ -41,7 +41,7 @@ public void process(GeneratingRegion region) {
CaveObjectFacet facet =
new CaveObjectFacet(region.getRegion(), region.getBorderForFacet(CaveObjectFacet.class));

Region3i worldRegion = facet.getWorldRegion();
BlockRegion worldRegion = facet.getWorldRegion();
int minY = worldRegion.minY();
int maxY = worldRegion.maxY();

Expand Down
5 changes: 3 additions & 2 deletions src/main/java/org/terasology/caves/CaveObjectRasterizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import com.google.common.collect.ImmutableList;
import com.google.common.collect.Maps;
import org.joml.Vector3ic;
import org.terasology.math.geom.BaseVector3i;
import org.terasology.registry.CoreRegistry;
import org.terasology.world.block.Block;
Expand Down Expand Up @@ -55,8 +56,8 @@ public void generateChunk(CoreChunk chunk, Region chunkRegion) {
CaveObjectFacet facet = chunkRegion.getFacet(CaveObjectFacet.class);
Block air = blockManager.getBlock(BlockManager.AIR_ID);

Map<BaseVector3i, CaveObjectType> entries = facet.getRelativeEntries();
for (BaseVector3i pos : entries.keySet()) {
Map<Vector3ic, CaveObjectType> entries = facet.getRelativeEntries();
for (Vector3ic pos : entries.keySet()) {

// check if some other rasterizer has already placed something here
if (chunk.getBlock(pos).equals(air)) {
Expand Down
3 changes: 2 additions & 1 deletion src/main/java/org/terasology/caves/CaveRasterizer.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package org.terasology.caves;

import org.terasology.math.JomlUtil;
import org.terasology.math.geom.Vector3i;
import org.terasology.registry.CoreRegistry;
import org.terasology.world.block.Block;
Expand Down Expand Up @@ -54,7 +55,7 @@ public void generateChunk(CoreChunk chunk, Region chunkRegion) {
}

for (Vector3i position : ChunkConstants.CHUNK_REGION) {
if (caveFacet.get(position)) {
if (caveFacet.get(JomlUtil.from(position))) {
chunk.setBlock(position, caveBlock);
}
}
Expand Down
43 changes: 22 additions & 21 deletions src/main/java/org/terasology/caves/CaveToSurfaceProvider.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

package org.terasology.caves;

import org.terasology.math.JomlUtil;
import org.terasology.math.geom.Vector3i;
import org.joml.Vector3i;
import org.joml.Vector3ic;
import org.terasology.world.generation.Facet;
import org.terasology.world.generation.FacetBorder;
import org.terasology.world.generation.FacetProviderPlugin;
Expand Down Expand Up @@ -49,14 +49,15 @@ public void process(GeneratingRegion region) {

Set<Vector3i> cavePositions = new HashSet<Vector3i>();

for (Vector3i pos : caveFacet.getWorldRegion()) {
if (caveFacet.getWorld(pos) && densityFacet.getWorldRegion().encompasses(pos) && surfacesFacet.getWorldRegion().encompasses(pos)) {
cavePositions.add(pos);
for (Vector3ic pos : caveFacet.getWorldRegion()) {
if (caveFacet.getWorld(pos) && densityFacet.getWorldRegion().contains(pos) && surfacesFacet.getWorldRegion().contains(pos)) {
cavePositions.add(new Vector3i(pos));
}
}

// Ensure that the ocean can't immediately fall into a cave.
for (Vector3i pos : densityFacet.getWorldRegion()) {
for (Vector3ic position : densityFacet.getWorldRegion()) {
Vector3i pos = new Vector3i(position);
if (densityFacet.getWorld(pos) <= 0) {
if (cavePositions.contains(pos)) {
cavePositions.remove(pos);
Expand All @@ -79,15 +80,15 @@ public void process(GeneratingRegion region) {
// Mark any cave floors exposed to the sky as surface.
Set<Vector3i> newSurfaces = new HashSet<>();
for (Vector3i pos : cavePositions) {
if (surfacesFacet.getWorld(JomlUtil.from(pos))) {
surfacesFacet.setWorld(JomlUtil.from(pos), false);
if (surfacesFacet.getWorld(pos)) {
surfacesFacet.setWorld(pos, false);
Vector3i newSurface = new Vector3i(pos);
while (cavePositions.contains(newSurface)) {
newSurface.addY(-1);
newSurface.add(0,-1,0);
}
if (newSurface.y >= surfacesFacet.getWorldRegion().minY()) {
newSurfaces.add(newSurface);
surfacesFacet.setWorld(JomlUtil.from(newSurface), true);
surfacesFacet.setWorld(newSurface, true);
}
}
}
Expand All @@ -97,27 +98,27 @@ public void process(GeneratingRegion region) {
Set<Vector3i> newerSurfaces = new HashSet<>();
for (Vector3i surface : newSurfaces) {
for (Vector3i adjacent : new Vector3i[]{
new Vector3i(surface).subX(1),
new Vector3i(surface).addX(1),
new Vector3i(surface).subZ(1),
new Vector3i(surface).addZ(1)
new Vector3i(surface).sub(1,0,0),
new Vector3i(surface).add(1,0,0),
new Vector3i(surface).sub(0,0,1),
new Vector3i(surface).add(0,0,1)
}) {
while (!cavePositions.contains(adjacent) && densityFacet.getWorldRegion().encompasses(adjacent) && densityFacet.getWorld(adjacent) > 0) {
adjacent.addY(1);
while (!cavePositions.contains(adjacent) && densityFacet.getWorldRegion().contains(adjacent) && densityFacet.getWorld(adjacent) > 0) {
adjacent.add(0,1,0);
}
// Only continue if the selected position is actually in a cave, rather than on the surface or above the selected region.
if (cavePositions.contains(adjacent)) {
while (cavePositions.contains(adjacent)) {
adjacent.subY(1);
adjacent.sub(0,1,0);
}
if (
surfacesFacet.getWorldRegion().encompasses(adjacent) &&
densityFacet.getWorldRegion().encompasses(adjacent) &&
surfacesFacet.getWorldRegion().contains(adjacent) &&
densityFacet.getWorldRegion().contains(adjacent) &&
densityFacet.getWorld(adjacent) > 0 &&
!surfacesFacet.getWorld(JomlUtil.from(adjacent))
!surfacesFacet.getWorld(adjacent)
) {
newerSurfaces.add(adjacent);
surfacesFacet.setWorld(JomlUtil.from(adjacent), true);
surfacesFacet.setWorld(adjacent, true);
}
}
}
Expand Down