Skip to content

Commit

Permalink
add the VehicleConstraint class
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengold committed Sep 28, 2024
1 parent cdb0a31 commit 138c6cb
Show file tree
Hide file tree
Showing 3 changed files with 355 additions and 0 deletions.
9 changes: 9 additions & 0 deletions src/main/java/com/github/stephengold/joltjni/Constraint.java
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,12 @@ abstract public class Constraint extends NonCopyable
// *************************************************************************
// constructors

/**
* Instantiate a constraint with no native object assigned.
*/
Constraint() {
}

/**
* Instantiate a constraint with the specified native object assigned but
* not owned.
Expand Down Expand Up @@ -88,6 +94,9 @@ static Constraint newConstraint(long constraintVa) {
case Slider:
result = new SliderConstraint(constraintVa);
break;
case Vehicle:
result = new VehicleConstraint(constraintVa);
break;
default:
throw new IllegalArgumentException("subType = " + subType);
}
Expand Down
203 changes: 203 additions & 0 deletions src/main/java/com/github/stephengold/joltjni/VehicleConstraint.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/*
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 com.github.stephengold.joltjni;

import com.github.stephengold.joltjni.readonly.Vec3Arg;

/**
* A constraint used in vehicle simulation.
*
* @author Stephen Gold [email protected]
*/
public class VehicleConstraint
extends Constraint
implements PhysicsStepListener {
// *************************************************************************
// constructors

/**
* protect the collision tester (if any) from garbage collection
*/
private VehicleCollisionTester tester;
// *************************************************************************
// constructors

/**
* Instantiate a constraint using the specified body and settings.
*
* @param body the body to which the constraint will apply (not null)
* @param settings the desired settings (not null, unaffected)
*/
public VehicleConstraint(Body body, VehicleConstraintSettings settings) {
long bodyVa = body.va();
long settingsVa = settings.va();
long constraintVa = createConstraint(bodyVa, settingsVa);
setVirtualAddress(constraintVa, false);
// not the owner due to ref counting
}

/**
* Instantiate a constraint with the specified native object assigned but
* not owned.
*
* @param constraintVa the virtual address of the native object to assign
* (not zero)
*/
VehicleConstraint(long constraintVa) {
super(constraintVa);
}
// *************************************************************************
// new methods exposed

/**
* Access the controller for this constraint.
*
* @return a new JVM object with the pre-existing native object assigned
*/
public VehicleController getController() {
long constraintVa = va();
long controllerVa = getController(constraintVa);
VehicleController result = new VehicleController(this, controllerVa);

return result;
}

/**
* Access the vehicle body.
*
* @return a new JVM object with the pre-existing native object assigned
*/
public Body getVehicleBody() {
long constraintVa = va();
long bodyVa = getVehicleBody(constraintVa);
Body result = new Body(bodyVa);

return result;
}

/**
* Access the underlying tester, if any.
*
* @return the pre-existing instance or {@code null} if none
*/
public VehicleCollisionTester getVehicleCollisionTester() {
return tester;
}

/**
* Access the specified wheel.
*
* @param wheelIndex the index of the wheel to access (≥0)
* @return a new JVM object with the pre-existing native object assigned
*/
public Wheel getWheel(int wheelIndex) {
long constraintVa = va();
long wheelVa = getWheel(constraintVa, wheelIndex);
Wheel result = new Wheel(wheelVa);

return result;
}

/**
* Copy the world transform of the specified wheel.
*
* @param wheelIndex the index of the wheel to query (≥0)
* @param right the wheel's axis of rotation (a unit vector in the wheel's
* model space)
* @param up the "up" direction (a unit vector in the wheel's model space)
* @return a new coordinate transform matrix
*/
public RMat44 getWheelWorldTransform(
int wheelIndex, Vec3Arg right, Vec3Arg up) {
long constraintVa = va();
float rx = right.getX();
float ry = right.getY();
float rz = right.getZ();
float ux = up.getX();
float uy = up.getY();
float uz = up.getZ();
long matrixVa = getWheelWorldTransform(
constraintVa, wheelIndex, rx, ry, rz, ux, uy, uz);
RMat44 result = new RMat44(matrixVa, true);

return result;
}

/**
* Return the number of simulation steps between wheel collision tests when
* the vehicle is active.
*
* @param numSteps the desired number of steps (0=never test, 1=test every
* step, 2=test every other step, default=1)
*/
public void setNumStepsBetweenCollisionTestActive(int numSteps) {
long constraintVa = va();
setNumStepsBetweenCollisionTestActive(constraintVa, numSteps);
}

/**
* Return the number of simulation steps between wheel collision tests when
* the vehicle is inactive.
*
* @param numSteps the desired number of steps (0=never, 1=every step,
* 2=every other step, default=1)
*/
public void setNumStepsBetweenCollisionTestInactive(int numSteps) {
long constraintVa = va();
setNumStepsBetweenCollisionTestInactive(constraintVa, numSteps);
}

/**
* Replace the collision tester.
*
* @param tester the desired tester (not null, alias created)
*/
public void setVehicleCollisionTester(VehicleCollisionTester tester) {
this.tester = tester;
long constraintVa = va();
long testerVa = tester.va();
setVehicleCollisionTester(constraintVa, testerVa);
}
// *************************************************************************
// native private methods

native private static long createConstraint(long bodyVa, long settingsVa);

native private static long getController(long constraintVa);

native private static long getVehicleBody(long constraintVa);

native private static long getWheel(long constraintVa, int wheelIndex);

native private static long getWheelWorldTransform(
long constraintVa, int wheelIndex, float rx, float ry, float rz,
float ux, float uy, float uz);

native private static void setNumStepsBetweenCollisionTestActive(
long constraintVa, int numSteps);

native private static void setNumStepsBetweenCollisionTestInactive(
long constraintVa, int numSteps);

native private static void setVehicleCollisionTester(
long constraintVa, long testerVa);
}
143 changes: 143 additions & 0 deletions src/main/native/glue/v/VehicleConstraint.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
/*
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.
*/

/*
* Author: Stephen Gold
*/
#include "Jolt/Jolt.h"
#include "Jolt/Physics/Vehicle/VehicleConstraint.h"
#include "auto/com_github_stephengold_joltjni_VehicleConstraint.h"
#include "glue/glue.h"

using namespace JPH;

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: createConstraint
* Signature: (JJ)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_createConstraint
(JNIEnv *, jclass, jlong bodyVa, jlong settingsVa) {
Body * const pBody = reinterpret_cast<Body *> (bodyVa);
VehicleConstraintSettings * const pSettings
= reinterpret_cast<VehicleConstraintSettings *> (settingsVa);
VehicleConstraint * const pResult
= new VehicleConstraint(*pBody, *pSettings);
TRACE_NEW("VehicleConstraint", pResult)
return reinterpret_cast<jlong> (pResult);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: getController
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_getController
(JNIEnv *, jclass, jlong constraintVa) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
VehicleController * const pResult = pConstraint->GetController();
return reinterpret_cast<jlong> (pResult);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: getVehicleBody
* Signature: (J)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_getVehicleBody
(JNIEnv *, jclass, jlong constraintVa) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
Body * const pResult = pConstraint->GetVehicleBody();
return reinterpret_cast<jlong> (pResult);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: getWheel
* Signature: (JI)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_getWheel
(JNIEnv *, jclass, jlong constraintVa, jint wheelIndex) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
Wheel * const pResult = pConstraint->GetWheel(wheelIndex);
return reinterpret_cast<jlong> (pResult);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: getWheelWorldTransform
* Signature: (JIFFFFFF)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_getWheelWorldTransform
(JNIEnv *, jclass, jlong constraintVa, jint wheelIndex, jfloat rx, jfloat ry, jfloat rz,
jfloat ux, jfloat uy, jfloat uz) {
const VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
const Vec3 right(rx, ry, rz);
const Vec3 up(ux, uy, uz);
const RMat44 matrix
= pConstraint->GetWheelWorldTransform(wheelIndex, right, up);
RMat44 * const pResult = new RMat44(matrix);
TRACE_NEW("RMat44", pResult)
return reinterpret_cast<jlong> (pResult);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: setNumStepsBetweenCollisionTestActive
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_setNumStepsBetweenCollisionTestActive
(JNIEnv *, jclass, jlong constraintVa, jint numSteps) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
pConstraint->SetNumStepsBetweenCollisionTestActive(numSteps);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: setNumStepsBetweenCollisionTestInactive
* Signature: (JI)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_setNumStepsBetweenCollisionTestInactive
(JNIEnv *, jclass, jlong constraintVa, jint numSteps) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
pConstraint->SetNumStepsBetweenCollisionTestInactive(numSteps);
}

/*
* Class: com_github_stephengold_joltjni_VehicleConstraint
* Method: setVehicleCollisionTester
* Signature: (JJ)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_VehicleConstraint_setVehicleCollisionTester
(JNIEnv *, jclass, jlong constraintVa, jlong testerVa) {
VehicleConstraint * const pConstraint
= reinterpret_cast<VehicleConstraint *> (constraintVa);
const VehicleCollisionTester * const pTester
= reinterpret_cast<VehicleCollisionTester *> (testerVa);
pConstraint->SetVehicleCollisionTester(pTester);
}

0 comments on commit 138c6cb

Please sign in to comment.