Skip to content

Commit

Permalink
BroadPhase: class redesign, including numerous API changes
Browse files Browse the repository at this point in the history
  • Loading branch information
stephengold committed Nov 13, 2024
1 parent 12e21a4 commit 72053c3
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 177 deletions.
118 changes: 22 additions & 96 deletions src/main/java/com/github/stephengold/joltjni/BroadPhase.java
Original file line number Diff line number Diff line change
Expand Up @@ -41,17 +41,6 @@ abstract public class BroadPhase extends BroadPhaseQuery {
// *************************************************************************
// new methods exposed

/**
* Abort adding bodies to the phase.
*
* @param bodyIds the IDs of the bodies to be added (not null, unmodified
* since the handle was created)
* @param addState the handle returned by {@code addBodiesPrepare()}
*/
public void addBodiesAbort(BodyId[] bodyIds, long addState) {
addBodiesAbort(bodyIds, bodyIds.length, addState);
}

/**
* Abort adding bodies to the phase.
*
Expand All @@ -60,24 +49,11 @@ public void addBodiesAbort(BodyId[] bodyIds, long addState) {
* @param numBodies the number of bodies to be added (≥0)
* @param addState the handle returned by {@code addBodiesPrepare()}
*/
public void addBodiesAbort(BodyId[] bodyIds, int numBodies, long addState) {
public void addBodiesAbort(
BodyIdArray bodyIds, int numBodies, long addState) {
long phaseVa = va();
int[] iasns = new int[numBodies];
for (int i = 0; i < numBodies; ++i) {
iasns[i] = bodyIds[i].getIndexAndSequenceNumber();
}
addBodiesAbort(phaseVa, iasns, numBodies, addState);
}

/**
* Finish adding bodies to the phase.
*
* @param bodyIds the IDs of the bodies to be added (not null, unmodified
* since the handle was created)
* @param addState the handle returned by {@code addBodiesPrepare()}
*/
public void addBodiesFinalize(BodyId[] bodyIds, long addState) {
addBodiesFinalize(bodyIds, bodyIds.length, addState);
long arrayVa = bodyIds.va();
addBodiesAbort(phaseVa, arrayVa, numBodies, addState);
}

/**
Expand All @@ -89,47 +65,25 @@ public void addBodiesFinalize(BodyId[] bodyIds, long addState) {
* @param addState the handle returned by {@code addBodiesPrepare()}
*/
public void addBodiesFinalize(
BodyId[] bodyIds, int numBodies, long addState) {
BodyIdArray bodyIds, int numBodies, long addState) {
long phaseVa = va();
int[] iasns = new int[numBodies];
for (int i = 0; i < numBodies; ++i) {
iasns[i] = bodyIds[i].getIndexAndSequenceNumber();
}
addBodiesFinalize(phaseVa, iasns, numBodies, addState);
long arrayVa = bodyIds.va();
addBodiesFinalize(phaseVa, arrayVa, numBodies, addState);
}

/**
* Prepare to add a batch of bodies to the phase.
*
* @param bodyIds the IDs of the bodies to be added (not null)
* @return a handle to be passed to {@code addBodiesFinalize()} or
* {@code addBodiesAbort()}
*/
public long addBodiesPrepare(BodyId... bodyIds) {
long result = addBodiesPrepare(bodyIds, bodyIds.length);
return result;
}

/**
* Prepare for adding multiple bodies to the phase.
*
* @param bodyIds the IDs of the bodies to be added (not null, possibly
* shuffled)
* @param numBodies the number of bodies to be added (&ge;0)
* @return a handle to be passed to {@code addBodiesFinalize()} or
* {@code addBodiesAbort()}
*/
public long addBodiesPrepare(BodyId[] bodyIds, int numBodies) {
public long addBodiesPrepare(BodyIdArray bodyIds, int numBodies) {
long phaseVa = va();
int[] iasns = new int[numBodies];
for (int i = 0; i < numBodies; ++i) {
iasns[i] = bodyIds[i].getIndexAndSequenceNumber();
}
long result = addBodiesPrepare(phaseVa, iasns, numBodies);
for (int i = 0; i < numBodies; ++i) {
int iasn = iasns[i];
bodyIds[i].setIndexAndSequenceNumber(iasn);
}
long arrayVa = bodyIds.va();
long result = addBodiesPrepare(phaseVa, arrayVa, numBodies);

return result;
}
Expand All @@ -156,22 +110,13 @@ public void optimize() {
optimize(phaseVa);
}

/**
* Invoke whenever the bounding boxes of some bodies change.
*
* @param bodyIds the IDs of the bodies to be notified (not null)
*/
public void notifyBodiesAabbChanged(BodyId... bodyIds) {
notifyBodiesAabbChanged(bodyIds, bodyIds.length, true);
}

/**
* Invoke whenever the bounding boxes of some bodies change.
*
* @param bodyIds the IDs of the bodies to be notified (not null)
* @param numBodies the number of bodies to be notified (&ge;0)
*/
public void notifyBodiesAabbChanged(BodyId[] bodyIds, int numBodies) {
public void notifyBodiesAabbChanged(BodyIdArray bodyIds, int numBodies) {
notifyBodiesAabbChanged(bodyIds, numBodies, true);
}

Expand All @@ -183,22 +128,10 @@ public void notifyBodiesAabbChanged(BodyId[] bodyIds, int numBodies) {
* @param takeLock {@code true} to acquire a lock, otherwise {@code false}
*/
public void notifyBodiesAabbChanged(
BodyId[] bodyIds, int numBodies, boolean takeLock) {
BodyIdArray bodyIds, int numBodies, boolean takeLock) {
long phaseVa = va();
int[] iasns = new int[numBodies];
for (int i = 0; i < numBodies; ++i) {
iasns[i] = bodyIds[i].getIndexAndSequenceNumber();
}
notifyBodiesAabbChanged(phaseVa, iasns, numBodies, takeLock);
}

/**
* Remove multiple bodies from the phase.
*
* @param bodyIds the IDs of the bodies to be removed (not null)
*/
public void removeBodies(BodyId... bodyIds) {
removeBodies(bodyIds, bodyIds.length);
long arrayVa = bodyIds.va();
notifyBodiesAabbChanged(phaseVa, arrayVa, numBodies, takeLock);
}

/**
Expand All @@ -208,37 +141,30 @@ public void removeBodies(BodyId... bodyIds) {
* shuffled)
* @param numBodies the number of bodies to be removed (&ge;0)
*/
public void removeBodies(BodyId[] bodyIds, int numBodies) {
public void removeBodies(BodyIdArray bodyIds, int numBodies) {
long phaseVa = va();
int[] iasns = new int[numBodies];
for (int i = 0; i < numBodies; ++i) {
iasns[i] = bodyIds[i].getIndexAndSequenceNumber();
}
removeBodies(phaseVa, iasns, numBodies);
for (int i = 0; i < numBodies; ++i) {
int iasn = iasns[i];
bodyIds[i].setIndexAndSequenceNumber(iasn);
}
long arrayVa = bodyIds.va();
removeBodies(phaseVa, arrayVa, numBodies);
}
// *************************************************************************
// native private methods

native private static void addBodiesAbort(
long phaseVa, int[] iasns, int numBodies, long addState);
long phaseVa, long arrayVa, int numBodies, long addState);

native private static void addBodiesFinalize(
long phaseVa, int[] iasns, int numBodies, long addState);
long phaseVa, long arrayVa, int numBodies, long addState);

native private static long addBodiesPrepare(
long phaseVa, int[] iasns, int numBodies);
long phaseVa, long arrayVa, int numBodies);

native private static void init(long phaseVa, long managerVa, long mapVa);

native private static void optimize(long phaseVa);

native private static void notifyBodiesAabbChanged(
long phaseVa, int[] iasns, int numBodies, boolean takeLock);
long phaseVa, long arrayVa, int numBodies, boolean takeLock);

native private static void removeBodies(
long phaseVa, int[] iasns, int numBodies);
long phaseVa, long arrayVa, int numBodies);
}
101 changes: 26 additions & 75 deletions src/main/native/glue/b/BroadPhase.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,79 +26,51 @@ SOFTWARE.
#include "Jolt/Jolt.h"
#include "Jolt/Physics/Collision/BroadPhase/BroadPhase.h"
#include "auto/com_github_stephengold_joltjni_BroadPhase.h"
#include "glue/glue.h"

using namespace JPH;

/*
* Class: com_github_stephengold_joltjni_BroadPhase
* Method: addBodiesAbort
* Signature: (J[IIJ)V
* Signature: (JJIJ)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BroadPhase_addBodiesAbort
(JNIEnv *pEnv, jclass, jlong phaseVa, jintArray iasns, jint numBodies,
(JNIEnv *, jclass, jlong phaseVa, jlong arrayVa, jint numBodies,
jlong addState) {
BroadPhase * const pPhase = reinterpret_cast<BroadPhase *> (phaseVa);
BodyID * const pTempArray = new BodyID[numBodies];
TRACE_NEW("BodyID[]", pTempArray)
jboolean isCopy;
jint * const pInts = pEnv->GetIntArrayElements(iasns, &isCopy);
for (int i = 0; i < numBodies; ++i) {
pTempArray[i] = BodyID(pInts[i]);
}
pEnv->ReleaseIntArrayElements(iasns, pInts, JNI_ABORT);
void * const pState = reinterpret_cast<void *> (addState);
pPhase->AddBodiesAbort(pTempArray, numBodies, pState);
TRACE_DELETE("BodyID[]", pTempArray)
delete[] pTempArray;
BodyID * const pArray = reinterpret_cast<BodyID *> (arrayVa);
BroadPhase::AddState const handle
= reinterpret_cast<BroadPhase::AddState> (addState);
pPhase->AddBodiesAbort(pArray, numBodies, handle);
}

/*
* Class: com_github_stephengold_joltjni_BroadPhase
* Method: addBodiesFinalize
* Signature: (J[IIJ)V
* Signature: (JJIJ)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BroadPhase_addBodiesFinalize
(JNIEnv *pEnv, jclass, jlong phaseVa, jintArray iasns, jint numBodies,
(JNIEnv *, jclass, jlong phaseVa, jlong arrayVa, jint numBodies,
jlong addState) {
BroadPhase * const pPhase = reinterpret_cast<BroadPhase *> (phaseVa);
BodyID * const pTempArray = new BodyID[numBodies];
TRACE_NEW("BodyID[]", pTempArray)
jboolean isCopy;
jint * const pInts = pEnv->GetIntArrayElements(iasns, &isCopy);
for (int i = 0; i < numBodies; ++i) {
pTempArray[i] = BodyID(pInts[i]);
}
pEnv->ReleaseIntArrayElements(iasns, pInts, JNI_ABORT);
void * const pState = reinterpret_cast<void *> (addState);
pPhase->AddBodiesAbort(pTempArray, numBodies, pState);
TRACE_DELETE("BodyID[]", pTempArray)
delete[] pTempArray;
BodyID * const pArray = reinterpret_cast<BodyID *> (arrayVa);
BroadPhase::AddState const handle
= reinterpret_cast<BroadPhase::AddState> (addState);
pPhase->AddBodiesFinalize(pArray, numBodies, handle);
}

/*
* Class: com_github_stephengold_joltjni_BroadPhase
* Method: addBodiesPrepare
* Signature: (J[II)J
* Signature: (JJI)J
*/
JNIEXPORT jlong JNICALL Java_com_github_stephengold_joltjni_BroadPhase_addBodiesPrepare
(JNIEnv *pEnv, jclass, jlong phaseVa, jintArray iasns, jint numBodies) {
(JNIEnv *, jclass, jlong phaseVa, jlong arrayVa, jint numBodies) {
BroadPhase * const pPhase = reinterpret_cast<BroadPhase *> (phaseVa);
BodyID * const pTempArray = new BodyID[numBodies];
TRACE_NEW("BodyID[]", pTempArray)
jboolean isCopy;
jint * const pInts = pEnv->GetIntArrayElements(iasns, &isCopy);
for (int i = 0; i < numBodies; ++i) {
pTempArray[i] = BodyID(pInts[i]);
}
void * const pResult = pPhase->AddBodiesPrepare(pTempArray, numBodies);
for (int i = 0; i < numBodies; ++i) {
pInts[i] = pTempArray[i].GetIndexAndSequenceNumber();
}
pEnv->ReleaseIntArrayElements(iasns, pInts, 0);
TRACE_DELETE("BodyID[]", pTempArray)
delete[] pTempArray;
return reinterpret_cast<jlong> (pResult);
BodyID * const pArray = reinterpret_cast<BodyID *> (arrayVa);
BroadPhase::AddState const handle
= pPhase->AddBodiesPrepare(pArray, numBodies);
return reinterpret_cast<jlong> (handle);
}

/*
Expand Down Expand Up @@ -129,45 +101,24 @@ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BroadPhase_optimize
/*
* Class: com_github_stephengold_joltjni_BroadPhase
* Method: notifyBodiesAabbChanged
* Signature: (J[IIZ)V
* Signature: (JJIZ)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BroadPhase_notifyBodiesAabbChanged
(JNIEnv *pEnv, jclass, jlong phaseVa, jintArray iasns, jint numBodies,
(JNIEnv *, jclass, jlong phaseVa, jlong arrayVa, jint numBodies,
jboolean takeLock) {
BroadPhase * const pPhase = reinterpret_cast<BroadPhase *> (phaseVa);
BodyID * const pTempArray = new BodyID[numBodies];
TRACE_NEW("BodyID[]", pTempArray)
jboolean isCopy;
jint * const pInts = pEnv->GetIntArrayElements(iasns, &isCopy);
for (int i = 0; i < numBodies; ++i) {
pTempArray[i] = BodyID(pInts[i]);
}
pEnv->ReleaseIntArrayElements(iasns, pInts, JNI_ABORT);
pPhase->NotifyBodiesAABBChanged(pTempArray, numBodies, takeLock);
TRACE_DELETE("BodyID[]", pTempArray)
delete[] pTempArray;
BodyID * const pArray = reinterpret_cast<BodyID *> (arrayVa);
pPhase->NotifyBodiesAABBChanged(pArray, numBodies, takeLock);
}

/*
* Class: com_github_stephengold_joltjni_BroadPhase
* Method: removeBodies
* Signature: (J[II)V
* Signature: (JJI)V
*/
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BroadPhase_removeBodies
(JNIEnv *pEnv, jclass, jlong phaseVa, jintArray iasns, jint numBodies) {
(JNIEnv *, jclass, jlong phaseVa, jlong arrayVa, jint numBodies) {
BroadPhase * const pPhase = reinterpret_cast<BroadPhase *> (phaseVa);
BodyID * const pTempArray = new BodyID[numBodies];
TRACE_NEW("BodyID[]", pTempArray)
jboolean isCopy;
jint * const pInts = pEnv->GetIntArrayElements(iasns, &isCopy);
for (int i = 0; i < numBodies; ++i) {
pTempArray[i] = BodyID(pInts[i]);
}
pPhase->RemoveBodies(pTempArray, numBodies);
for (int i = 0; i < numBodies; ++i) {
pInts[i] = pTempArray[i].GetIndexAndSequenceNumber();
}
pEnv->ReleaseIntArrayElements(iasns, pInts, 0);
TRACE_DELETE("BodyID[]", pTempArray)
delete[] pTempArray;
BodyID * const pArray = reinterpret_cast<BodyID *> (arrayVa);
pPhase->RemoveBodies(pArray, numBodies);
}
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@ public void Initialize()

// Add all bodies to the broadphase
List<Body> body_vector = mBodyManager.getBodies().toList();
BodyId[] bodies_to_add = new BodyId [num_bodies];
BodyIdArray bodies_to_add = new BodyIdArray (num_bodies);
for (int b = 0; b < num_bodies; ++b)
bodies_to_add[b] = body_vector.get(b).getId();
bodies_to_add.set(b, body_vector.get(b).getId());
long add_state = mBroadPhase.addBodiesPrepare(bodies_to_add, num_bodies);
mBroadPhase.addBodiesFinalize(bodies_to_add, num_bodies, add_state);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,24 +64,24 @@ public void PrePhysicsUpdate( PreUpdateParams inParams)
if (mCurrentBody > 0)
{
final int cNumBodiesToMove = 100;
BodyId[] bodies_to_move = new BodyId [cNumBodiesToMove];
BodyIdArray bodies_to_move = new BodyIdArray (cNumBodiesToMove);
UniformIntDistribution body_selector = new UniformIntDistribution(0, (int)mCurrentBody - 1);
UniformRealDistribution translation_selector = new UniformRealDistribution(1.0f, 5.0f);
for (int i = 0; i < cNumBodiesToMove; ++i)
{
Body body = body_vector.get(body_selector.nextInt(mRandomGenerator));
assert(body.isInBroadPhase());
body.setPositionAndRotationInternal(Op.add(body.getPosition() , Op.multiply(translation_selector.nextFloat(mRandomGenerator) , Vec3.sRandom(mRandomGenerator))), Quat.sIdentity());
bodies_to_move[i] = body.getId();
bodies_to_move.set(i, body.getId());
}
mBroadPhase.notifyBodiesAabbChanged(bodies_to_move, cNumBodiesToMove);
TestUtils.testClose(bodies_to_move);
}

// Create batch of bodies
BodyId[] bodies_to_add_or_remove = new BodyId [num_this_step];
BodyIdArray bodies_to_add_or_remove = new BodyIdArray (num_this_step);
for (int b = 0; b < num_this_step; ++b)
bodies_to_add_or_remove[b] = body_vector.get(mCurrentBody + b).getId();
bodies_to_add_or_remove.set(b, body_vector.get(mCurrentBody + b).getId());

// Add/remove them
if (mDirection == 1)
Expand Down

0 comments on commit 72053c3

Please sign in to comment.