From 22f683b9488ccadb653234674a2f95fadf0a358f Mon Sep 17 00:00:00 2001 From: stephengold Date: Sun, 24 Nov 2024 16:30:45 -0800 Subject: [PATCH] samples.general: add 5 more tests --- .../testjoltjni/app/samples/SmokeTestAll.java | 5 + .../general/FrictionPerTriangleTest.java | 123 +++++++++++++ .../app/samples/general/FrictionTest.java | 60 ++++++ .../app/samples/general/FunnelTest.java | 172 ++++++++++++++++++ .../samples/general/GravityFactorTest.java | 49 +++++ .../samples/general/GyroscopicForceTest.java | 58 ++++++ 6 files changed, 467 insertions(+) create mode 100644 src/test/java/testjoltjni/app/samples/general/FrictionPerTriangleTest.java create mode 100644 src/test/java/testjoltjni/app/samples/general/FrictionTest.java create mode 100644 src/test/java/testjoltjni/app/samples/general/FunnelTest.java create mode 100644 src/test/java/testjoltjni/app/samples/general/GravityFactorTest.java create mode 100644 src/test/java/testjoltjni/app/samples/general/GyroscopicForceTest.java diff --git a/src/test/java/testjoltjni/app/samples/SmokeTestAll.java b/src/test/java/testjoltjni/app/samples/SmokeTestAll.java index 6094ed02..d7193f9f 100644 --- a/src/test/java/testjoltjni/app/samples/SmokeTestAll.java +++ b/src/test/java/testjoltjni/app/samples/SmokeTestAll.java @@ -128,6 +128,11 @@ public static void main(String... arguments) { smokeTest(new DampingTest()); smokeTest(new DynamicMeshTest()); smokeTest(new EnhancedInternalEdgeRemovalTest()); + smokeTest(new FrictionPerTriangleTest()); + smokeTest(new FrictionTest()); + smokeTest(new FunnelTest()); + smokeTest(new GravityFactorTest()); + smokeTest(new GyroscopicForceTest()); smokeTest(new HighSpeedTest()); smokeTest(new RestitutionTest()); diff --git a/src/test/java/testjoltjni/app/samples/general/FrictionPerTriangleTest.java b/src/test/java/testjoltjni/app/samples/general/FrictionPerTriangleTest.java new file mode 100644 index 00000000..b9924c69 --- /dev/null +++ b/src/test/java/testjoltjni/app/samples/general/FrictionPerTriangleTest.java @@ -0,0 +1,123 @@ +/* +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.samples.general; +import com.github.stephengold.joltjni.*; +import com.github.stephengold.joltjni.enumerate.*; +import com.github.stephengold.joltjni.readonly.*; +import java.util.*; +import testjoltjni.app.samples.*; +import static com.github.stephengold.joltjni.Jolt.*; +import static com.github.stephengold.joltjni.std.Std.*; +/** + * A line-for-line Java translation of the Jolt Physics friction per-triangle test. + *

+ * Compare with the original by Jorrit Rouwe at + * https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/FrictionPerTriangleTest.cpp + */ +public class FrictionPerTriangleTest extends Test{ +static class MyMaterial extends PhysicsMaterialSimple{ + float mFriction,mRestitution; + MyMaterial(String inName,ConstColor inColor,float inFriction,float inRestitution){ + super(inName, inColor); + mFriction=inFriction; + mRestitution=inRestitution; + }; +} + +public void Initialize() +{ + final int num_sections = 5; + final float section_size = 50.0f; + + // Create a strip of triangles + List triangles=new ArrayList<>(2*num_sections+2); + for (int z = 0; z <= num_sections; ++z) + { + float z1 = section_size * (z - 0.5f * num_sections); + float z2 = z1 + section_size; + + Float3 v1 =new Float3(-100.0f, 0, z1); + Float3 v2 =new Float3(100.0f, 0, z1); + Float3 v3 =new Float3(-100.0f, 0, z2); + Float3 v4 =new Float3(100.0f, 0, z2); + + triangles.add(new Triangle(v1, v3, v4, z)); + triangles.add(new Triangle(v1, v4, v2, z)); + } + + // Create materials with increasing friction + PhysicsMaterialList materials=new PhysicsMaterialList(); + for (int i = 0; i <= num_sections; ++i) + { + float friction = (float)(i) / (float)(num_sections); + materials.pushBack(new MyMaterial("Friction " + Float.toString(friction), Color.sGetDistinctColor(i), friction, 0.0f).toRef()); + } + + // A ramp + mBodyInterface.createAndAddBody(new BodyCreationSettings(new MeshShapeSettings(triangles, materials), RVec3.sZero(), Quat.sRotation(Vec3.sAxisX(), 0.2f * JPH_PI), EMotionType.Static, Layers.NON_MOVING), EActivation.DontActivate); + + // A box with friction 1 that slides down the ramp + ShapeRef box_shape = new BoxShape(new Vec3(2.0f, 2.0f, 2.0f), cDefaultConvexRadius, new MyMaterial("Box Friction 1", Color.sYellow, 1.0f, 0.0f)).toRef(); + mBodyInterface.createAndAddBody(new BodyCreationSettings(box_shape,new RVec3(0, 60.0f, -75.0f), Quat.sRotation(Vec3.sAxisX(), 0.2f * JPH_PI), EMotionType.Dynamic, Layers.MOVING), EActivation.Activate); +} + +void sGetFrictionAndRestitution(ConstBody inBody, ConstSubShapeId inSubShapeID, float []outFriction, float []outRestitution) +{ + // Get the material that corresponds to the sub shape ID + ConstPhysicsMaterial material = inBody.getShape().getMaterial(inSubShapeID); + if (material.targetVa() == PhysicsMaterial.sDefault().targetVa()) + { + // This is the default material, use the settings from the body (note all bodies in our test have a material so this should not happen) + outFriction[0] = inBody.getFriction(); + outRestitution[0] = inBody.getRestitution(); + } + else + { + // If it's not the default material we know its a material that we created so we can cast it and get the values + MyMaterial my_material = (MyMaterial)(material); + outFriction[0] = my_material.mFriction; + outRestitution[0] = my_material.mRestitution; + } +} + +void sOverrideContactSettings(ConstBody inBody1, ConstBody inBody2, ContactManifold inManifold, ContactSettings ioSettings) +{ + // Get the custom friction and restitution for both bodies + float[] friction1=new float[1], friction2=new float[1], restitution1=new float[1], restitution2=new float[1]; + sGetFrictionAndRestitution(inBody1, inManifold.getSubShapeId1(), friction1, restitution1); + sGetFrictionAndRestitution(inBody2, inManifold.getSubShapeId2(), friction2, restitution2); + + // Use the default formulas for combining friction and restitution + ioSettings.setCombinedFriction ( sqrt(friction1[0] * friction2[0])); + ioSettings.setCombinedRestitution ( Math.max(restitution1[0], restitution2[0])); +} + +void OnContactAdded(ConstBody inBody1, ConstBody inBody2, ContactManifold inManifold, ContactSettings ioSettings) +{ + sOverrideContactSettings(inBody1, inBody2, inManifold, ioSettings); +} + +void OnContactPersisted(ConstBody inBody1, ConstBody inBody2, ContactManifold inManifold, ContactSettings ioSettings) +{ + sOverrideContactSettings(inBody1, inBody2, inManifold, ioSettings); +} +} diff --git a/src/test/java/testjoltjni/app/samples/general/FrictionTest.java b/src/test/java/testjoltjni/app/samples/general/FrictionTest.java new file mode 100644 index 00000000..c041f6cb --- /dev/null +++ b/src/test/java/testjoltjni/app/samples/general/FrictionTest.java @@ -0,0 +1,60 @@ +/* +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.samples.general; +import com.github.stephengold.joltjni.*; +import com.github.stephengold.joltjni.enumerate.*; +import testjoltjni.app.samples.*; +import static com.github.stephengold.joltjni.Jolt.*; +/** + * A line-for-line Java translation of the Jolt Physics friction test. + *

+ * Compare with the original by Jorrit Rouwe at + * https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/FrictionTest.cpp + */ +public class FrictionTest extends Test{ + +public void Initialize() +{ + // Floor + Body floor = mBodyInterface.createBody(new BodyCreationSettings(new BoxShape(new Vec3(100.0f, 1.0f, 100.0f), 0.0f), RVec3.sZero(), Quat.sRotation(Vec3.sAxisX(), 0.25f * JPH_PI), EMotionType.Static, Layers.NON_MOVING)); + floor.setFriction(1.0f); + mBodyInterface.addBody(floor.getId(), EActivation.DontActivate); + + ShapeRefC box = new BoxShape(new Vec3(2.0f, 2.0f, 2.0f)).toRefC(); + ShapeRefC sphere = new SphereShape(2.0f).toRefC(); + + // Bodies with increasing friction + for (int i = 0; i <= 10; ++i) + { + Body body = mBodyInterface.createBody(new BodyCreationSettings(box,new RVec3(-50.0f + i * 10.0f, 55.0f, -50.0f), Quat.sRotation(Vec3.sAxisX(), 0.25f * JPH_PI), EMotionType.Dynamic, Layers.MOVING)); + body.setFriction(0.1f * i); + mBodyInterface.addBody(body.getId(), EActivation.Activate); + } + + for (int i = 0; i <= 10; ++i) + { + Body body = mBodyInterface.createBody(new BodyCreationSettings(sphere,new RVec3(-50.0f + i * 10.0f, 47.0f, -40.0f), Quat.sRotation(Vec3.sAxisX(), 0.25f * JPH_PI), EMotionType.Dynamic, Layers.MOVING)); + body.setFriction(0.1f * i); + mBodyInterface.addBody(body.getId(), EActivation.Activate); + } +} +} diff --git a/src/test/java/testjoltjni/app/samples/general/FunnelTest.java b/src/test/java/testjoltjni/app/samples/general/FunnelTest.java new file mode 100644 index 00000000..5580f079 --- /dev/null +++ b/src/test/java/testjoltjni/app/samples/general/FunnelTest.java @@ -0,0 +1,172 @@ +/* +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.samples.general; +import com.github.stephengold.joltjni.*; +import com.github.stephengold.joltjni.enumerate.*; +import com.github.stephengold.joltjni.readonly.*; +import com.github.stephengold.joltjni.std.*; +import java.util.*; +import testjoltjni.app.samples.*; +import testjoltjni.app.testframework.CameraState; +import static com.github.stephengold.joltjni.Jolt.*; +import static com.github.stephengold.joltjni.operator.Op.*; +/** + * A line-for-line Java translation of the Jolt Physics funnel test. + *

+ * Compare with the original by Jorrit Rouwe at + * https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/FunnelTest.cpp + */ +public class FunnelTest extends Test{ + +public void Initialize() +{ + ShapeRefC box = new BoxShape(new Vec3(50, 1, 50), 0.0f).toRefC(); + + // Funnel + for (int i = 0; i < 4; ++i) + { + Quat rotation = Quat.sRotation(Vec3.sAxisY(), 0.5f * JPH_PI * i); + + mBodyInterface.createAndAddBody(new BodyCreationSettings(box,new RVec3(star(rotation ,new Vec3(25, 25, 0))), star(rotation , Quat.sRotation(Vec3.sAxisZ(), 0.25f * JPH_PI)), EMotionType.Static, Layers.NON_MOVING), EActivation.DontActivate); + } + + DefaultRandomEngine random=new DefaultRandomEngine(); + UniformRealDistribution feature_size=new UniformRealDistribution(0.1f, 2.0f); + UniformRealDistribution position_variation=new UniformRealDistribution(-40, 40); + UniformRealDistribution scale_variation=new UniformRealDistribution(-1.5f, 1.5f); + + // Random scale + Vec3 scale=new Vec3(scale_variation.nextFloat(random), scale_variation.nextFloat(random), scale_variation.nextFloat(random)); + + // Make it minimally -0.5 or 0.5 depending on the sign + plusEquals(scale , Vec3.sSelect(Vec3.sReplicate(-0.5f), Vec3.sReplicate(0.5f), Vec3.sGreaterOrEqual(scale, Vec3.sZero()))); + + ShapeRefC shape=new ShapeRefC(); + for (int i = 0; i < 1000; ++i) + { + switch (random.nextInt() % 10) + { + case 0: + { + shape = new SphereShape(feature_size.nextFloat(random)).toRefC(); + scale = scale.swizzle(0,0,0); // Only uniform scale supported + break; + } + + case 1: + { + shape = new BoxShape(new Vec3(feature_size.nextFloat(random), feature_size.nextFloat(random), feature_size.nextFloat(random))).toRefC(); + break; + } + + case 2: + { + // Create random points + List points=new ArrayList<>(20); + for (int j = 0; j < 20; ++j) + points.add(star(feature_size.nextFloat(random) , Vec3.sRandom(random))); + shape =new ConvexHullShapeSettings(points).create().get(); + break; + } + + case 3: + { + shape = new CapsuleShape(0.5f * feature_size.nextFloat(random), feature_size.nextFloat(random)).toRefC(); + scale = scale.swizzle(0,0,0); // Only uniform scale supported + break; + } + + case 4: + { + float top = feature_size.nextFloat(random); + float bottom = feature_size.nextFloat(random); + float half_height = Math.max(0.5f * feature_size.nextFloat(random), 0.5f * Math.abs(top - bottom) + 0.001f); + shape =new TaperedCapsuleShapeSettings(half_height, top, bottom).create().get(); + scale = scale.swizzle(0,0,0); // Only uniform scale supported + break; + } + + case 5: + { + shape = new CylinderShape(0.5f * feature_size.nextFloat(random), feature_size.nextFloat(random)).toRefC(); + scale = scale.swizzle(0,1,0); // Scale X must be same as Z + break; + } + + case 6: + { + shape =new TaperedCylinderShapeSettings(0.5f * feature_size.nextFloat(random), feature_size.nextFloat(random), feature_size.nextFloat(random)).create().get(); + scale = scale.swizzle(0,1,0); // Scale X must be same as Z + break; + } + + case 7: + { + shape =new TaperedCylinderShapeSettings(0.5f * feature_size.nextFloat(random), 0.0f, feature_size.nextFloat(random), 0.0f).create().get(); + scale = scale.swizzle(0,0,0); // Scale X must be same as Z + break; + } + + case 8: + { + // Simple compound + StaticCompoundShapeSettings compound_shape_settings=new StaticCompoundShapeSettings(); + compound_shape_settings.addShape(Vec3.sZero(), Quat.sIdentity(), new CapsuleShape(1, 0.1f)); + compound_shape_settings.addShape(new Vec3(0, -1, 0), Quat.sIdentity(), new SphereShape(0.5f)); + compound_shape_settings.addShape(new Vec3(0, 1, 0), Quat.sIdentity(), new SphereShape(0.5f)); + shape = compound_shape_settings.create().get(); + scale = scale.swizzle(0,0,0); // Only uniform scale supported + break; + } + + case 9: + { + // Compound with sub compound and rotation + StaticCompoundShapeSettings sub_compound = new StaticCompoundShapeSettings(); + sub_compound.addShape(new Vec3(0, 0.75f, 0), Quat.sRotation(Vec3.sAxisZ(), 0.5f * JPH_PI), new BoxShape(new Vec3(0.75f, 0.25f, 0.2f))); + sub_compound.addShape(new Vec3(0.75f, 0, 0), Quat.sRotation(Vec3.sAxisZ(), 0.5f * JPH_PI), new CylinderShape(0.75f, 0.2f).toRefC()); + sub_compound.addShape(new Vec3(0, 0, 0.75f), Quat.sRotation(Vec3.sAxisX(), 0.5f * JPH_PI), new TaperedCapsuleShapeSettings(0.75f, 0.25f, 0.2f)); + StaticCompoundShapeSettings compound_shape_settings=new StaticCompoundShapeSettings(); + compound_shape_settings.addShape(new Vec3(0, 0, 0), star(Quat.sRotation(Vec3.sAxisX(), -0.25f * JPH_PI) , Quat.sRotation(Vec3.sAxisZ(), 0.25f * JPH_PI)), sub_compound); + compound_shape_settings.addShape(new Vec3(0, -0.1f, 0), star(Quat.sRotation(Vec3.sAxisX(), 0.25f * JPH_PI) , Quat.sRotation(Vec3.sAxisZ(), -0.75f * JPH_PI)), sub_compound); + shape = compound_shape_settings.create().get(); + scale = scale.swizzle(0,0,0); // Only uniform scale supported + break; + } + } + + // Scale the shape + if ((random.nextInt() % 3) == 0) + shape = new ScaledShape(shape, scale).toRefC(); + + RVec3 position=new RVec3(position_variation.nextFloat(random), 100.0f + position_variation.nextFloat(random), position_variation.nextFloat(random)); + mBodyInterface.createAndAddBody(new BodyCreationSettings(shape, position, Quat.sRandom(random), EMotionType.Dynamic, Layers.MOVING), EActivation.Activate); + } +} + +void GetInitialCamera(CameraState ioState) +{ + RVec3 cam_tgt =new RVec3(0, 50, 0); + ioState.mPos =new RVec3(50, 100, 50); + ioState.mForward =new Vec3(minus(cam_tgt , ioState.mPos)).normalized(); +} +} diff --git a/src/test/java/testjoltjni/app/samples/general/GravityFactorTest.java b/src/test/java/testjoltjni/app/samples/general/GravityFactorTest.java new file mode 100644 index 00000000..d60af05e --- /dev/null +++ b/src/test/java/testjoltjni/app/samples/general/GravityFactorTest.java @@ -0,0 +1,49 @@ +/* +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.samples.general; +import com.github.stephengold.joltjni.*; +import com.github.stephengold.joltjni.enumerate.*; +import testjoltjni.app.samples.*; +/** + * A line-for-line Java translation of the Jolt Physics gravity-factor test. + *

+ * Compare with the original by Jorrit Rouwe at + * https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/GravityFactorTest.cpp + */ +public class GravityFactorTest extends Test{ + +public void Initialize() +{ + // Floor + CreateFloor(); + + ShapeRefC box = new BoxShape(new Vec3(2.0f, 2.0f, 2.0f)).toRefC(); + + // Bodies with increasing gravity fraction + for (int i = 0; i <= 10; ++i) + { + Body body = mBodyInterface.createBody(new BodyCreationSettings(box,new RVec3(-50.0f + i * 10.0f, 25.0f, 0), Quat.sIdentity(), EMotionType.Dynamic, Layers.MOVING)); + body.getMotionProperties().setGravityFactor(0.1f * i); + mBodyInterface.addBody(body.getId(), EActivation.Activate); + } +} +} diff --git a/src/test/java/testjoltjni/app/samples/general/GyroscopicForceTest.java b/src/test/java/testjoltjni/app/samples/general/GyroscopicForceTest.java new file mode 100644 index 00000000..bc3baae6 --- /dev/null +++ b/src/test/java/testjoltjni/app/samples/general/GyroscopicForceTest.java @@ -0,0 +1,58 @@ +/* +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.samples.general; +import com.github.stephengold.joltjni.*; +import com.github.stephengold.joltjni.enumerate.*; +import testjoltjni.app.samples.*; +import static com.github.stephengold.joltjni.operator.Op.*; +/** + * A line-for-line Java translation of the Jolt Physics gyroscopic-force test. + *

+ * Compare with the original by Jorrit Rouwe at + * https://github.com/jrouwe/JoltPhysics/blob/master/Samples/Tests/General/GyroscopicForceTest.cpp + */ +public class GyroscopicForceTest extends Test{ + +public void Initialize() +{ + // Floor + CreateFloor(); + + StaticCompoundShapeSettings compound=new StaticCompoundShapeSettings(); + compound.addShape(Vec3.sZero(), Quat.sIdentity(), new BoxShape(new Vec3(0.5f, 5.0f, 0.5f))); + compound.addShape(new Vec3(1.5f, 0, 0), Quat.sIdentity(), new BoxShape(new Vec3(1.0f, 0.5f, 0.5f))); + compound.setEmbedded(); + + // One body without gyroscopic force + BodyCreationSettings bcs=new BodyCreationSettings(compound,new RVec3(0, 10, 0), Quat.sIdentity(), EMotionType.Dynamic, Layers.MOVING); + bcs.setLinearDamping ( 0.0f); + bcs.setAngularDamping ( 0.0f); + bcs.setAngularVelocity (new Vec3(10, 1, 0)); + bcs.setGravityFactor ( 0.0f); + mBodyInterface.createAndAddBody(bcs, EActivation.Activate); + + // One body with gyroscopic force + bcs.setPosition (plus(bcs.getPosition(),new RVec3(10, 0, 0))); + bcs.setApplyGyroscopicForce ( true); + mBodyInterface.createAndAddBody(bcs, EActivation.Activate); +} +}