-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
implement an automated test using JUnit 4
- Loading branch information
1 parent
2a5edc8
commit 9ec66fc
Showing
9 changed files
with
771 additions
and
3 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,6 +4,8 @@ | |
|
||
[libraries] | ||
|
||
junit4 = "junit:junit:4.13.2" | ||
|
||
[bundles] | ||
|
||
[plugins] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,160 @@ | ||
/* | ||
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. | ||
*/ | ||
|
||
import com.github.stephengold.joltjni.Body; | ||
import com.github.stephengold.joltjni.BodyCreationSettings; | ||
import com.github.stephengold.joltjni.BodyId; | ||
import com.github.stephengold.joltjni.BodyInterface; | ||
import com.github.stephengold.joltjni.BoxShapeSettings; | ||
import com.github.stephengold.joltjni.EActivation; | ||
import com.github.stephengold.joltjni.EMotionType; | ||
import com.github.stephengold.joltjni.EPhysicsUpdateError; | ||
import com.github.stephengold.joltjni.JobSystemThreadPool; | ||
import com.github.stephengold.joltjni.Jolt; | ||
import com.github.stephengold.joltjni.MapObj2Bp; | ||
import com.github.stephengold.joltjni.ObjVsBpFilter; | ||
import com.github.stephengold.joltjni.ObjVsObjFilter; | ||
import com.github.stephengold.joltjni.PhysicsSystem; | ||
import com.github.stephengold.joltjni.Quat; | ||
import com.github.stephengold.joltjni.RVec3; | ||
import com.github.stephengold.joltjni.Shape; | ||
import com.github.stephengold.joltjni.SphereShape; | ||
import com.github.stephengold.joltjni.TempAllocatorImpl; | ||
import com.github.stephengold.joltjni.Vec3; | ||
import org.junit.Assert; | ||
import org.junit.Test; | ||
|
||
/** | ||
* An automated test for jolt-jni using JUnit 4. | ||
* | ||
* @author Stephen Gold [email protected] | ||
*/ | ||
public class Test001 { | ||
/** | ||
* Drop a dynamic spherical ball on a static box. | ||
* <p> | ||
* Derived from HelloWorld.cpp by Jorrit Rouwe. | ||
*/ | ||
@Test | ||
public void test001() { | ||
Utils.loadNativeLibrary(); | ||
Jolt.registerDefaultAllocator(); | ||
Jolt.installDefaultTraceCallback(); | ||
Jolt.installDefaultAssertCallback(); | ||
Jolt.newFactory(); | ||
Jolt.registerTypes(); | ||
|
||
final int numBytes = 1 << 18; // 256 KiB | ||
TempAllocatorImpl allocator = new TempAllocatorImpl(numBytes); | ||
|
||
final int maxJobs = 64; | ||
final int maxBarriers = 4; | ||
int numThreads = Utils.numThreads(); | ||
JobSystemThreadPool jobSystem | ||
= new JobSystemThreadPool(maxJobs, maxBarriers, numThreads); | ||
|
||
final int objLayerNonMoving = 0; | ||
final int objLayerMoving = 1; | ||
final int numObjLayers = 2; | ||
final int bpLayerNonMoving = 0; | ||
final int bpLayerMoving = 1; | ||
final int numBpLayers = 2; | ||
|
||
MapObj2Bp mapObj2Bp = new MapObj2Bp(numObjLayers, numBpLayers) | ||
.add(objLayerNonMoving, bpLayerNonMoving) | ||
.add(objLayerMoving, bpLayerMoving); | ||
|
||
ObjVsBpFilter objVsBpFilter | ||
= new ObjVsBpFilter(numObjLayers, numBpLayers) | ||
.disablePair(objLayerNonMoving, bpLayerNonMoving); | ||
|
||
ObjVsObjFilter objVsObjFilter = new ObjVsObjFilter(numObjLayers) | ||
.disablePair(objLayerNonMoving, objLayerNonMoving); | ||
|
||
final int maxBodies = 4; | ||
final int numBodyMutexes = 0; // 0 means "use the default value" | ||
final int maxBodyPairs = 4; | ||
final int maxContacts = 4; | ||
PhysicsSystem physicsSystem = new PhysicsSystem( | ||
maxBodies, numBodyMutexes, maxBodyPairs, maxContacts, | ||
mapObj2Bp, objVsBpFilter, objVsObjFilter); | ||
BodyInterface bodyInterface = physicsSystem.getBodyInterface(); | ||
|
||
BoxShapeSettings floorShapeSettings | ||
= new BoxShapeSettings(new Vec3(100f, 1f, 100f)); | ||
RVec3 floorLocation = new RVec3(0.0, -1.0, 0.0); | ||
Quat orientation = new Quat(); | ||
BodyCreationSettings floorBodySettings | ||
= new BodyCreationSettings(floorShapeSettings, floorLocation, | ||
orientation, EMotionType.Static, objLayerNonMoving); | ||
Body floor = bodyInterface.createBody(floorBodySettings); | ||
BodyId floorId = floor.getId(); | ||
bodyInterface.addBody(floorId, EActivation.DontActivate); | ||
|
||
Shape ballShape = new SphereShape(0.5f); | ||
RVec3 ballLocation = new RVec3(0.0, 2.0, 0.0); | ||
BodyCreationSettings ballSettings = new BodyCreationSettings( | ||
ballShape, ballLocation, orientation, | ||
EMotionType.Dynamic, objLayerMoving); | ||
Body ball = bodyInterface.createBody(ballSettings); | ||
BodyId ballId = ball.getId(); | ||
bodyInterface.addBody(ballId, EActivation.Activate); | ||
Vec3 ballVelocity = new Vec3(0f, -5f, 0f); | ||
bodyInterface.setLinearVelocity(ballId, ballVelocity); | ||
|
||
physicsSystem.optimizeBroadPhase(); | ||
|
||
int stepCounter = 0; | ||
while (bodyInterface.isActive(ballId) && stepCounter < 99) { | ||
final float deltaTime = 1 / 60f; | ||
int errors | ||
= physicsSystem.update(deltaTime, 1, allocator, jobSystem); | ||
Assert.assertEquals(EPhysicsUpdateError.None, errors); | ||
++stepCounter; | ||
} | ||
|
||
Assert.assertEquals(48, stepCounter); | ||
|
||
ballLocation = bodyInterface.getCenterOfMassPosition(ballId); | ||
Utils.assertEquals(0f, 0.48f, 0f, ballLocation, 1e-5f); | ||
|
||
ballVelocity = bodyInterface.getLinearVelocity(ballId); | ||
Utils.assertEquals(0f, 0f, 0f, ballVelocity, 1e-5f); | ||
|
||
bodyInterface.removeBody(ballId); | ||
bodyInterface.destroyBody(ballId); | ||
|
||
bodyInterface.removeBody(floorId); | ||
bodyInterface.destroyBody(floorId); | ||
|
||
floorShapeSettings.close(); | ||
physicsSystem.close(); | ||
objVsObjFilter.close(); | ||
objVsBpFilter.close(); | ||
mapObj2Bp.close(); | ||
jobSystem.close(); | ||
allocator.close(); | ||
|
||
Jolt.unregisterTypes(); | ||
Jolt.destroyFactory(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,141 @@ | ||
/* | ||
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. | ||
*/ | ||
|
||
import com.github.stephengold.joltjni.Jolt; | ||
import com.github.stephengold.joltjni.Quat; | ||
import com.github.stephengold.joltjni.RVec3; | ||
import com.github.stephengold.joltjni.Vec3; | ||
import com.jme3.system.NativeLibraryLoader; | ||
import java.io.File; | ||
import org.junit.Assert; | ||
|
||
/** | ||
* Utility methods for automated testing of jolt-jni libraries. | ||
* | ||
* @author Stephen Gold [email protected] | ||
*/ | ||
final public class Utils { | ||
// ************************************************************************* | ||
// constructors | ||
|
||
/** | ||
* A private constructor to inhibit instantiation of this class. | ||
*/ | ||
private Utils() { | ||
// do nothing | ||
} | ||
// ************************************************************************* | ||
// new methods exposed | ||
|
||
/** | ||
* Verify that 2 quaternions are equal to within some tolerance. | ||
* | ||
* @param x the expected X component | ||
* @param y the expected Y component | ||
* @param z the expected Z component | ||
* @param w the expected W component | ||
* @param actual the Quaternion to test (not null, unaffected) | ||
* @param tolerance the allowable difference for each component (≥0) | ||
*/ | ||
public static void assertEquals(float x, float y, float z, float w, | ||
Quat actual, float tolerance) { | ||
Assert.assertEquals("x component", x, actual.getX(), tolerance); | ||
Assert.assertEquals("y component", y, actual.getY(), tolerance); | ||
Assert.assertEquals("z component", z, actual.getZ(), tolerance); | ||
Assert.assertEquals("w component", w, actual.getW(), tolerance); | ||
} | ||
|
||
/** | ||
* Verify that 2 position-precision vectors are equal to within some | ||
* tolerance. | ||
* | ||
* @param x the expected X component | ||
* @param y the expected Y component | ||
* @param z the expected Z component | ||
* @param actual the vector to test (not null, unaffected) | ||
* @param tolerance the allowable difference for each component (≥0) | ||
*/ | ||
public static void assertEquals( | ||
float x, float y, float z, RVec3 actual, float tolerance) { | ||
Assert.assertEquals("x component", x, actual.x(), tolerance); | ||
Assert.assertEquals("y component", y, actual.y(), tolerance); | ||
Assert.assertEquals("z component", z, actual.z(), tolerance); | ||
} | ||
|
||
/** | ||
* Verify that 2 single-precision vectors are equal to within some | ||
* tolerance. | ||
* | ||
* @param x the expected X component | ||
* @param y the expected Y component | ||
* @param z the expected Z component | ||
* @param actual the vector to test (not null, unaffected) | ||
* @param tolerance the allowable difference for each component (≥0) | ||
*/ | ||
public static void assertEquals( | ||
float x, float y, float z, Vec3 actual, float tolerance) { | ||
Assert.assertEquals("x component", x, actual.getX(), tolerance); | ||
Assert.assertEquals("y component", y, actual.getY(), tolerance); | ||
Assert.assertEquals("z component", z, actual.getZ(), tolerance); | ||
} | ||
|
||
/** | ||
* Load some flavor of Debug native library. | ||
* <p> | ||
* The search order is: | ||
* <ol> | ||
* <li>DebugSp</li> | ||
* <li>DebugDp</li> | ||
* </ol> | ||
*/ | ||
public static void loadNativeLibrary() { | ||
boolean fromDist = false; | ||
File directory = new File("build/libs/joltjni/shared"); | ||
|
||
boolean success = NativeLibraryLoader.loadJoltJni( | ||
fromDist, directory, "Debug", "Sp"); | ||
if (success) { | ||
Assert.assertFalse(Jolt.isDoublePrecision()); | ||
} else { | ||
success = NativeLibraryLoader.loadJoltJni( | ||
fromDist, directory, "Debug", "Dp"); | ||
if (success) { | ||
Assert.assertTrue(Jolt.isDoublePrecision()); | ||
} | ||
} | ||
Assert.assertTrue(success); | ||
} | ||
|
||
/** | ||
* Return the number of threads to use. | ||
* | ||
* @return the count (≥1) | ||
*/ | ||
public static int numThreads() { | ||
int result = Runtime.getRuntime().availableProcessors() - 1; | ||
if (result < 1) { | ||
result = 1; | ||
} | ||
|
||
return result; | ||
} | ||
} |
Oops, something went wrong.