From 274e195596d96ebfcf14ec17cc52b34a5ca80a62 Mon Sep 17 00:00:00 2001 From: stephengold Date: Tue, 5 Nov 2024 11:02:10 -0800 Subject: [PATCH] implement Perlin noise --- .gitignore | 1 + build.gradle | 16 ++++++++++- .../com/github/stephengold/joltjni/Jolt.java | 17 +++++++++++ src/main/native/TestFramework.h | 1 + src/main/native/glue/j/Jolt.cpp | 12 ++++++++ .../java/testjoltjni/app/samples/Test.java | 5 ++-- .../shapes/DeformedHeightFieldShapeTest.java | 3 +- .../testjoltjni/app/testframework/Perlin.java | 28 ------------------- 8 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 src/main/native/TestFramework.h delete mode 100644 src/test/java/testjoltjni/app/testframework/Perlin.java diff --git a/.gitignore b/.gitignore index b10710cf..d26a6449 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ /downloads/ /src/main/native/auto/ /src/main/native/Jolt/ +/src/main/native/TestFramework/ # Ignore Gradle's project-specific cache directory: /.gradle/ diff --git a/build.gradle b/build.gradle index 93bedd49..d4b9bfd2 100644 --- a/build.gradle +++ b/build.gradle @@ -23,7 +23,7 @@ ext { // Regenerate all JNI header files and unpack Jolt before compiling any C++ code. tasks.withType(CppCompile) { - dependsOn('classes', 'compileTestJava', 'unpackJoltSource') + dependsOn('classes', 'compileTestJava', 'unpackJoltSource', 'unpackTestFramework') } String javaHome = org.gradle.internal.jvm.Jvm.current().javaHome.absolutePath @@ -97,6 +97,7 @@ model { sources.cpp.source { srcDir 'src/main/native/Jolt' + srcDir 'src/main/native/TestFramework/Math' srcDir 'src/main/native/glue' include '**/*.cpp' } @@ -150,6 +151,7 @@ model { cppCompiler.args "/I$javaHome/include" cppCompiler.args "/I$javaHome/include/win32" cppCompiler.args "/I$projectDir/src/main/native" + cppCompiler.args "/I$projectDir/src/main/native/TestFramework" // for Math/Perlin.h cppCompiler.args '/std:c++17' if (isDebug) { @@ -167,6 +169,7 @@ model { cppCompiler.args '-I', "$javaHome/include" cppCompiler.args '-I', "$projectDir/src/main/native" + cppCompiler.args '-I', "$projectDir/src/main/native/TestFramework" // for Math/Perlin.h cppCompiler.args '-std=c++17' cppCompiler.args '-Werror=return-type' @@ -448,6 +451,17 @@ tasks.register('unpackJoltSource', Copy) { } into layout.projectDirectory.dir('src/main/native/Jolt') } +tasks.register('unpackTestFramework', Copy) { + dependsOn 'downloadJoltSource' + from (zipTree(downloadZip)) { + include 'JoltPhysics-5.2.0/TestFramework/**' + eachFile { fcd -> + fcd.relativePath = new RelativePath(true, fcd.relativePath.segments.drop(2)) + } + includeEmptyDirs = false + } + into layout.projectDirectory.dir('src/main/native/TestFramework') +} // Register cleanup tasks: diff --git a/src/main/java/com/github/stephengold/joltjni/Jolt.java b/src/main/java/com/github/stephengold/joltjni/Jolt.java index 740daf2b..ee17ecab 100644 --- a/src/main/java/com/github/stephengold/joltjni/Jolt.java +++ b/src/main/java/com/github/stephengold/joltjni/Jolt.java @@ -216,6 +216,23 @@ public static IntBuffer newDirectIntBuffer(int numInts) { return result; } + /** + * Generate 3-D Perlin noise. + * + * @param x the X coordinate + * @param y the Y coordinate + * @param z the Z coordinate + * @param xWrap the wraparound interval for the X coordinate (power of 2) or + * 0 for don't care + * @param yWrap the wraparound interval for the Y coordinate (power of 2) or + * 0 for don't care + * @param zWrap the wraparound interval for the Z coordinate (power of 2) or + * 0 for don't care + * @return a sample value + */ + native public static float perlinNoise3( + float x, float y, float z, int xWrap, int yWrap, int zWrap); + /** * Dump profiler data. * diff --git a/src/main/native/TestFramework.h b/src/main/native/TestFramework.h new file mode 100644 index 00000000..319b8404 --- /dev/null +++ b/src/main/native/TestFramework.h @@ -0,0 +1 @@ +// This file was added to mask the Jolt Physics TestFramework.h, which is Windows-specific. \ No newline at end of file diff --git a/src/main/native/glue/j/Jolt.cpp b/src/main/native/glue/j/Jolt.cpp index aaf081a0..8522d06c 100644 --- a/src/main/native/glue/j/Jolt.cpp +++ b/src/main/native/glue/j/Jolt.cpp @@ -31,6 +31,7 @@ SOFTWARE. #include "Jolt/Geometry/RayAABox.h" #include "Jolt/Physics/DeterminismLog.h" #include "Jolt/RegisterTypes.h" +#include "TestFramework/Math/Perlin.h" #include "auto/com_github_stephengold_joltjni_Jolt.h" #include "glue/glue.h" @@ -207,6 +208,17 @@ JNIEXPORT jboolean JNICALL Java_com_github_stephengold_joltjni_Jolt_isDoublePrec #endif } +/* + * Class: com_github_stephengold_joltjni_Jolt + * Method: perlinNoise3 + * Signature: (FFFIII)F + */ +JNIEXPORT jfloat JNICALL Java_com_github_stephengold_joltjni_Jolt_perlinNoise3 + (JNIEnv *, jclass, jfloat x, jfloat y, jfloat z, jint xWrap, jint yWrap, jint zWrap) { + const float result = PerlinNoise3(x, y, z, xWrap, yWrap, zWrap); + return result; +} + /* * Class: com_github_stephengold_joltjni_Jolt * Method: profileDump diff --git a/src/test/java/testjoltjni/app/samples/Test.java b/src/test/java/testjoltjni/app/samples/Test.java index 544065b9..96996e3a 100644 --- a/src/test/java/testjoltjni/app/samples/Test.java +++ b/src/test/java/testjoltjni/app/samples/Test.java @@ -24,7 +24,6 @@ of this software and associated documentation files (the "Software"), to deal import com.github.stephengold.joltjni.enumerate.*; import com.github.stephengold.joltjni.operator.Op; import java.util.*; -import testjoltjni.app.testframework.*; /** * A line-for-line Java translation of the Jolt Physics abstract test class. @@ -145,7 +144,7 @@ public Body CreateMeshTerrain() float[][] heights = new float[n + 1][n + 1]; for (int x = 0; x <= n; ++x) for (int z = 0; z <= n; ++z) - heights[x][z] = max_height * Perlin.Noise3((float)(x) * 8.0f / n, 0, (float)(z) * 8.0f / n, 256, 256, 256); + heights[x][z] = max_height * Jolt.perlinNoise3((float)(x) * 8.0f / n, 0, (float)(z) * 8.0f / n, 256, 256, 256); // Create regular grid of triangles List triangles = new ArrayList<>(2 * n * n); @@ -186,7 +185,7 @@ public Body CreateHeightFieldTerrain() float[] heights = new float[n * n]; for (int y = 0; y < n; ++y) for (int x = 0; x < n; ++x) - heights[y * n + x] = max_height * Perlin.Noise3((float)(x) * 8.0f / n, 0, (float)(y) * 8.0f / n, 256, 256, 256); + heights[y * n + x] = max_height * Jolt.perlinNoise3((float)(x) * 8.0f / n, 0, (float)(y) * 8.0f / n, 256, 256, 256); // Create height field ShapeSettings height_field = new HeightFieldShapeSettings(heights, new Vec3(-0.5f * cell_size * n, 0.0f, -0.5f * cell_size * n), new Vec3(cell_size, 1.0f, cell_size), n); diff --git a/src/test/java/testjoltjni/app/samples/shapes/DeformedHeightFieldShapeTest.java b/src/test/java/testjoltjni/app/samples/shapes/DeformedHeightFieldShapeTest.java index 953c7ea9..827a17b6 100644 --- a/src/test/java/testjoltjni/app/samples/shapes/DeformedHeightFieldShapeTest.java +++ b/src/test/java/testjoltjni/app/samples/shapes/DeformedHeightFieldShapeTest.java @@ -26,7 +26,6 @@ of this software and associated documentation files (the "Software"), to deal import java.nio.FloatBuffer; import java.util.function.BiFunction; import testjoltjni.app.samples.*; -import testjoltjni.app.testframework.Perlin; /** * A line-for-line Java translation of the Jolt Physics deformed heightfield-shape test. *

@@ -51,7 +50,7 @@ public void Initialize() mHeightSamples=new float[cSampleCount * cSampleCount]; for (int y = 0; y < cSampleCount; ++y) for (int x = 0; x < cSampleCount; ++x) - mHeightSamples[y * cSampleCount + x] = cMaxHeight * Perlin.Noise3((float)(x) * 8.0f / cSampleCount, 0, (float)(y) * 8.0f / cSampleCount, 256, 256, 256); + mHeightSamples[y * cSampleCount + x] = cMaxHeight * Jolt.perlinNoise3((float)(x) * 8.0f / cSampleCount, 0, (float)(y) * 8.0f / cSampleCount, 256, 256, 256); // Determine scale and offset of the terrain Vec3 offset=new Vec3(-0.5f * cCellSize * cSampleCount, 0, -0.5f * cCellSize * cSampleCount); diff --git a/src/test/java/testjoltjni/app/testframework/Perlin.java b/src/test/java/testjoltjni/app/testframework/Perlin.java deleted file mode 100644 index ac392ed9..00000000 --- a/src/test/java/testjoltjni/app/testframework/Perlin.java +++ /dev/null @@ -1,28 +0,0 @@ -/* -Copyright (c) 2024 Stephen Gold - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. - */ -package testjoltjni.app.testframework; - -public class Perlin { - public static float Noise3(float x, float y, float z, int x_wrap, int y_wrap, int z_wrap) { - throw new UnsupportedOperationException(); - } -}