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

Fix terrain brush tools for rotated/scaled terrain #161

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
1 change: 1 addition & 0 deletions editor/CHANGES
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
- Water creation dialog
- Helper lines
- Show renamed game object's new name after rename in Inspector
- Fix terrain brush tools for rotated and scaled terrain

[0.4.2] ~ 10/24/2022
- Fix shader compilation error for Terrain when using normal maps
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import com.badlogic.gdx.graphics.Pixmap;
import com.badlogic.gdx.math.Interpolation;
import com.badlogic.gdx.math.MathUtils;
import com.badlogic.gdx.math.Matrix4;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.math.Vector3;
import com.badlogic.gdx.math.collision.Ray;
Expand Down Expand Up @@ -104,6 +105,7 @@ public ModeNotSupportedException(String message) {
protected static final Vector3 tVec0 = new Vector3();
protected static final Vector3 tVec1 = new Vector3();
protected static final Vector3 tVec2 = new Vector3();
private static final Matrix4 tmpMatrix = new Matrix4();

// all brushes share the some common settings
private static final GlobalBrushSettingsChangedEvent brushSettingsChangedEvent = new GlobalBrushSettingsChangedEvent();
Expand Down Expand Up @@ -175,9 +177,12 @@ private void paint() {
SplatMap sm = terrain.getTerrainTexture().getSplatmap();
if (sm == null) return;

Vector3 terrainPos = getTerrainPosition(tVec1);
final float splatX = ((brushPos.x - terrainPos.x) / (float) terrain.terrainWidth) * sm.getWidth();
final float splatY = ((brushPos.z - terrainPos.z) / (float) terrain.terrainDepth) * sm.getHeight();
// should convert world position to terrain local position
tVec1.set(brushPos);
tVec1.mul(tmpMatrix.set(terrainComponent.getModelInstance().transform).inv());

final float splatX = (tVec1.x / (float) terrain.terrainWidth) * sm.getWidth();
final float splatY = (tVec1.z / (float) terrain.terrainDepth) * sm.getHeight();
final float splatRad = (radius / terrain.terrainWidth) * sm.getWidth();
final Pixmap pixmap = sm.getPixmap();

Expand All @@ -203,7 +208,6 @@ private void paint() {
*/
private void smooth() {
Terrain terrain = terrainAsset.getTerrain();
final Vector3 terPos = getTerrainPosition(tVec1);

int weights = 0;
float totalHeights = 0;
Expand All @@ -212,10 +216,10 @@ private void smooth() {
for (int x = 0; x < terrain.vertexResolution; x++) {
for (int z = 0; z < terrain.vertexResolution; z++) {
final Vector3 vertexPos = terrain.getVertexPosition(tVec0, x, z);
vertexPos.x += terPos.x;
vertexPos.z += terPos.z;

// should convert world position to terrain local position
tVec2.set(brushPos);
tVec2.mul(tmpMatrix.set(terrainComponent.getModelInstance().transform).inv());
tVec2.y = vertexPos.y;
float distance = vertexPos.dst(tVec2);

Expand All @@ -232,11 +236,10 @@ private void smooth() {
for (int x = 0; x < terrain.vertexResolution; x++) {
for (int z = 0; z < terrain.vertexResolution; z++) {
final Vector3 vertexPos = terrain.getVertexPosition(tVec0, x, z);
vertexPos.x += terPos.x;
vertexPos.z += terPos.z;
vertexPos.y += terPos.y;

// should convert world position to terrain local position
tVec2.set(brushPos);
tVec2.mul(tmpMatrix.set(terrainComponent.getModelInstance().transform).inv());
tVec2.y = vertexPos.y;
float distance = vertexPos.dst(tVec2);

Expand All @@ -259,15 +262,13 @@ private void smooth() {

private void flatten() {
Terrain terrain = terrainAsset.getTerrain();
final Vector3 terPos = getTerrainPosition(tVec1);
for (int x = 0; x < terrain.vertexResolution; x++) {
for (int z = 0; z < terrain.vertexResolution; z++) {
final Vector3 vertexPos = terrain.getVertexPosition(tVec0, x, z);
vertexPos.x += terPos.x;
vertexPos.z += terPos.z;
vertexPos.y += terPos.y;

// should convert world position to terrain local position
tVec2.set(brushPos);
tVec2.mul(tmpMatrix.set(terrainComponent.getModelInstance().transform).inv());
tVec2.y = vertexPos.y;
float distance = vertexPos.dst(tVec2);

Expand All @@ -277,7 +278,7 @@ private void flatten() {
if (diff <= 1f) {
terrain.heightData[index] = heightSample;
} else if (diff > 1f) {
final float elevation = getValueOfBrushPixmap(brushPos.x, brushPos.z, vertexPos.x, vertexPos.z,
final float elevation = getValueOfBrushPixmap(tVec2.x, tVec2.z, vertexPos.x, vertexPos.z,
radius);
// current height is lower than sample
if(heightSample > terrain.heightData[index]) {
Expand All @@ -302,22 +303,21 @@ private void flatten() {

private void raiseLower(BrushAction action) {
Terrain terrain = terrainAsset.getTerrain();
final Vector3 terPos = getTerrainPosition(tVec1);
float dir = (action == BrushAction.PRIMARY) ? 1 : -1;
for (int x = 0; x < terrain.vertexResolution; x++) {
for (int z = 0; z < terrain.vertexResolution; z++) {
final Vector3 vertexPos = terrain.getVertexPosition(tVec0, x, z);
vertexPos.x += terPos.x;
vertexPos.z += terPos.z;

// for the dist calc, we do not want to factor in global Y height
// should convert world position to terrain local position
tVec2.set(brushPos);
tVec2.mul(tmpMatrix.set(terrainComponent.getModelInstance().transform).inv());
// for the dist calc, we do not want to factor in global Y height
tVec2.y = vertexPos.y;

float distance = vertexPos.dst(tVec2);

if (distance <= radius) {
float elevation = getValueOfBrushPixmap(brushPos.x, brushPos.z, vertexPos.x, vertexPos.z, radius);
float elevation = getValueOfBrushPixmap(tVec2.x, tVec2.z, vertexPos.x, vertexPos.z, radius);
terrain.heightData[z * terrain.vertexResolution + x] += dir * elevation * strength;
}
}
Expand Down