Skip to content

Commit e930a78

Browse files
authored
Switch BatchBodyInterface to use the new array classes (#40)
1 parent 5cf2f17 commit e930a78

File tree

3 files changed

+79
-98
lines changed

3 files changed

+79
-98
lines changed

src/main/java/com/github/stephengold/joltjni/BatchBodyInterface.java

Lines changed: 22 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,16 @@ public void getCenterOfMassPositions(
160160
* Return the center-of-mass transforms of the specified bodies.
161161
*
162162
* @param bodyIds the IDs of the bodies to locate (not null)
163-
* @param storeMatrices storage for the matrices (not null, 16 doubles per
164-
* body, interleaved, modified)
163+
* @param storeMatrices storage for the matrices (not null, modified)
165164
*/
166165
public void getCenterOfMassTransforms(
167-
BodyIdArray bodyIds, DoubleBuffer storeMatrices) {
166+
BodyIdArray bodyIds, RMat44Array storeMatrices) {
168167
int numBodies = bodyIds.length();
169-
assert storeMatrices.capacity() >= numBodies * 16;
170168
long bodyInterfaceVa = va();
171169
long arrayVa = bodyIds.va();
170+
long matricesVa = storeMatrices.va();
172171
getCenterOfMassTransforms(
173-
bodyInterfaceVa, arrayVa, numBodies, storeMatrices);
172+
bodyInterfaceVa, arrayVa, numBodies, matricesVa);
174173
}
175174

176175
/**
@@ -210,17 +209,16 @@ public void getGravityFactors(BodyIdArray bodyIds,
210209
* Copy the inverses of the inertia tensors in system coordinates.
211210
*
212211
* @param bodyIds the IDs of the bodies to query (not null)
213-
* @param storeMatrices storage for the matrices (not null, 16 floats per
214-
* body, interleaved, modified)
212+
* @param storeMatrices storage for the matrices (not null, modified)
215213
*/
216214
public void getInverseInertias(
217-
BodyIdArray bodyIds, FloatBuffer storeMatrices) {
215+
BodyIdArray bodyIds, Mat44Array storeMatrices) {
218216
int numBodies = bodyIds.length();
219-
assert storeMatrices.capacity() >= numBodies * 16;
220217
long bodyInterfaceVa = va();
221218
long arrayVa = bodyIds.va();
219+
long matricesVa = storeMatrices.va();
222220
getInverseInertias(
223-
bodyInterfaceVa, arrayVa, numBodies, storeMatrices);
221+
bodyInterfaceVa, arrayVa, numBodies, matricesVa);
224222
}
225223

226224
/**
@@ -339,41 +337,31 @@ public void getRotations(
339337
* Access the shapes of the specified bodies.
340338
*
341339
* @param bodyIds the IDs of the bodies (not null)
342-
* @return a new array of new references
340+
* @param storeShapes storage for the references (not null, modified)
343341
*/
344-
public ShapeRefC[] getShapes(BodyIdArray bodyIds) {
342+
public void getShapes(BodyIdArray bodyIds, ShapeRefCArray storeShapes) {
345343
int numBodies = bodyIds.length();
346-
LongBuffer storeShapeVas = Jolt.newDirectLongBuffer(numBodies);
347344
long bodyInterfaceVa = va();
348345
long arrayVa = bodyIds.va();
349-
getShapes(bodyInterfaceVa, arrayVa, numBodies, storeShapeVas);
350-
ShapeRefC[] result = new ShapeRefC[numBodies];
351-
for (int i = 0; i < numBodies; ++i) {
352-
long va = storeShapeVas.get(i);
353-
result[i] = new ShapeRefC(va, true);
354-
}
355-
return result;
346+
long shapesVa = storeShapes.va();
347+
getShapes(bodyInterfaceVa, arrayVa, numBodies, shapesVa);
356348
}
357349

358350
/**
359351
* Generate transformed shapes for the specified bodies.
360352
*
361353
* @param bodyIds the IDs of the bodies (not null)
362-
* @return a new array of new objects
354+
* @param storeShapes storage for the transformed shapes (not null,
355+
* modified)
363356
*/
364-
public TransformedShape[] getTransformedShapes(BodyIdArray bodyIds) {
357+
public void getTransformedShapes(
358+
BodyIdArray bodyIds, TransformedShapeArray storeShapes) {
365359
int numBodies = bodyIds.length();
366-
LongBuffer storeShapeVas = Jolt.newDirectLongBuffer(numBodies);
367360
long bodyInterfaceVa = va();
368361
long arrayVa = bodyIds.va();
362+
long shapesVa = storeShapes.va();
369363
getTransformedShapes(
370-
bodyInterfaceVa, arrayVa, numBodies, storeShapeVas);
371-
TransformedShape[] result = new TransformedShape[numBodies];
372-
for (int i = 0; i < numBodies; ++i) {
373-
long va = storeShapeVas.get(i);
374-
result[i] = new TransformedShape(va, true);
375-
}
376-
return result;
364+
bodyInterfaceVa, arrayVa, numBodies, shapesVa);
377365
}
378366

379367
/**
@@ -555,7 +543,7 @@ native private static void getCenterOfMassPositions(long bodyInterfaceVa,
555543
long arrayVa, int numBodies, DoubleBuffer storePositions);
556544

557545
native private static void getCenterOfMassTransforms(long bodyInterfaceVa,
558-
long arrayVa, int numBodies, DoubleBuffer storeMatrices);
546+
long arrayVa, int numBodies, long matricesVa);
559547

560548
native private static void getFrictions(long bodyInterfaceVa, long arrayVa,
561549
int numBodies, FloatBuffer storeFrictions);
@@ -564,7 +552,7 @@ native private static void getGravityFactors(long bodyInterfaceVa,
564552
long arrayVa, int numBodies, FloatBuffer storeFactors);
565553

566554
native private static void getInverseInertias(long bodyInterfaceVa,
567-
long arrayVa, int numBodies, FloatBuffer storeMatrices);
555+
long arrayVa, int numBodies, long matricesVa);
568556

569557
native private static void getLinearVelocities(long bodyInterfaceVa,
570558
long arrayVa, int numBodies, FloatBuffer storeVelocities);
@@ -588,10 +576,10 @@ native private static void getRotations(long bodyInterfaceVa, long arrayVa,
588576
int numBodies, FloatBuffer storeOrientations);
589577

590578
native private static void getShapes(long bodyInterfaceVa, long arrayVa,
591-
int numBodies, LongBuffer storeShapeVas);
579+
int numBodies, long shapesVa);
592580

593581
native private static void getTransformedShapes(long bodyInterfaceVa,
594-
long arrayVa, int numBodies, LongBuffer storeShapeVas);
582+
long arrayVa, int numBodies, long shapesVa);
595583

596584
native private static void getUseManifoldReductions(long bodyInterfaceVa,
597585
long arrayVa, int numBodies, ByteBuffer storeStatus);

src/main/native/glue/ba/BatchBodyInterface.cpp

Lines changed: 20 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -151,31 +151,17 @@ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_ge
151151
/*
152152
* Class: com_github_stephengold_joltjni_BatchBodyInterface
153153
* Method: getCenterOfMassTransforms
154-
* Signature: (JJILjava/nio/DoubleBuffer;)V
154+
* Signature: (JJIJ)V
155155
*/
156156
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_getCenterOfMassTransforms
157-
(JNIEnv *pEnv, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
158-
jobject storeMatrices) {
157+
(JNIEnv *, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
158+
jlong matricesVa) {
159159
const BodyInterface * const pInterface
160160
= reinterpret_cast<BodyInterface *> (bodyInterfaceVa);
161161
const BodyID * const pArray = reinterpret_cast<const BodyID *> (arrayVa);
162-
DIRECT_DOUBLE_BUFFER(pEnv, storeMatrices, pOut, capacity);
163-
JPH_ASSERT(capacity >= numBodies * 16);
162+
RMat44 * const pMatrices = reinterpret_cast<RMat44 *> (matricesVa);
164163
for (jlong i = 0; i < numBodies; ++i) {
165-
RMat44 m = pInterface->GetCenterOfMassTransform(pArray[i]);
166-
jlong offset = i * 16;
167-
for (uint col = 0; col < 3; ++col) {
168-
Vec4 v = m.GetColumn4(col);
169-
pOut[offset + col * 4 + 0] = (jdouble) v.GetX();
170-
pOut[offset + col * 4 + 1] = (jdouble) v.GetY();
171-
pOut[offset + col * 4 + 2] = (jdouble) v.GetZ();
172-
pOut[offset + col * 4 + 3] = (jdouble) v.GetW();
173-
}
174-
RVec3 t = m.GetTranslation();
175-
pOut[offset + 12] = (jdouble) t.GetX();
176-
pOut[offset + 13] = (jdouble) t.GetY();
177-
pOut[offset + 14] = (jdouble) t.GetZ();
178-
pOut[offset + 15] = 1.0;
164+
pMatrices[i] = pInterface->GetCenterOfMassTransform(pArray[i]);
179165
}
180166
}
181167

@@ -218,26 +204,17 @@ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_ge
218204
/*
219205
* Class: com_github_stephengold_joltjni_BatchBodyInterface
220206
* Method: getInverseInertias
221-
* Signature: (JJILjava/nio/FloatBuffer;)V
207+
* Signature: (JJIJ)V
222208
*/
223209
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_getInverseInertias
224-
(JNIEnv *pEnv, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
225-
jobject storeMatrices) {
210+
(JNIEnv *, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
211+
jlong matricesVa) {
226212
const BodyInterface * const pInterface
227213
= reinterpret_cast<BodyInterface *> (bodyInterfaceVa);
228214
const BodyID * const pArray = reinterpret_cast<const BodyID *> (arrayVa);
229-
DIRECT_FLOAT_BUFFER(pEnv, storeMatrices, pOut, capacity);
230-
JPH_ASSERT(capacity >= numBodies * 16);
215+
Mat44 * const pMatrices = reinterpret_cast<Mat44 *> (matricesVa);
231216
for (jlong i = 0; i < numBodies; ++i) {
232-
Mat44 m = pInterface->GetInverseInertia(pArray[i]);
233-
jlong offset = i * 16;
234-
for (uint col = 0; col < 4; ++col) {
235-
Vec4 v = m.GetColumn4(col);
236-
pOut[offset + col * 4 + 0] = v.GetX();
237-
pOut[offset + col * 4 + 1] = v.GetY();
238-
pOut[offset + col * 4 + 2] = v.GetZ();
239-
pOut[offset + col * 4 + 3] = v.GetW();
240-
}
217+
pMatrices[i] = pInterface->GetInverseInertia(pArray[i]);
241218
}
242219
}
243220

@@ -380,42 +357,34 @@ JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_ge
380357
/*
381358
* Class: com_github_stephengold_joltjni_BatchBodyInterface
382359
* Method: getShapes
383-
* Signature: (JJILjava/nio/LongBuffer;)V
360+
* Signature: (JJIJ)V
384361
*/
385362
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_getShapes
386-
(JNIEnv *pEnv, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
387-
jobject storeShapeVas) {
363+
(JNIEnv *, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
364+
jlong shapesVa) {
388365
const BodyInterface * const pInterface
389366
= reinterpret_cast<BodyInterface *> (bodyInterfaceVa);
390367
const BodyID * const pArray = reinterpret_cast<const BodyID *> (arrayVa);
391-
DIRECT_LONG_BUFFER(pEnv, storeShapeVas, pOut, capacity);
392-
JPH_ASSERT(capacity >= numBodies);
368+
ShapeRefC * const pShapes = reinterpret_cast<ShapeRefC *> (shapesVa);
393369
for (jlong i = 0; i < numBodies; ++i) {
394-
ShapeRefC * const pResult = new ShapeRefC();
395-
TRACE_NEW("ShapeRefC", pResult)
396-
*pResult = pInterface->GetShape(pArray[i]);
397-
pOut[i] = reinterpret_cast<jlong> (pResult);
370+
pShapes[i] = pInterface->GetShape(pArray[i]);
398371
}
399372
}
400373

401374
/*
402375
* Class: com_github_stephengold_joltjni_BatchBodyInterface
403376
* Method: getTransformedShapes
404-
* Signature: (JJILjava/nio/LongBuffer;)V
377+
* Signature: (JJIJ)V
405378
*/
406379
JNIEXPORT void JNICALL Java_com_github_stephengold_joltjni_BatchBodyInterface_getTransformedShapes
407-
(JNIEnv *pEnv, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
408-
jobject storeShapeVas) {
380+
(JNIEnv *, jclass, jlong bodyInterfaceVa, jlong arrayVa, jint numBodies,
381+
jlong shapesVa) {
409382
const BodyInterface * const pInterface
410383
= reinterpret_cast<BodyInterface *> (bodyInterfaceVa);
411384
const BodyID * const pArray = reinterpret_cast<const BodyID *> (arrayVa);
412-
DIRECT_LONG_BUFFER(pEnv, storeShapeVas, pOut, capacity);
413-
JPH_ASSERT(capacity >= numBodies);
385+
TransformedShape * const pShapes = reinterpret_cast<TransformedShape *> (shapesVa);
414386
for (jlong i = 0; i < numBodies; ++i) {
415-
TransformedShape * const pResult = new TransformedShape();
416-
TRACE_NEW("TransformedShape", pResult)
417-
*pResult = pInterface->GetTransformedShape(pArray[i]);
418-
pOut[i] = reinterpret_cast<jlong> (pResult);
387+
pShapes[i] = pInterface->GetTransformedShape(pArray[i]);
419388
}
420389
}
421390

src/test/java/testjoltjni/junit/BodyBatchQueryTest.java

Lines changed: 37 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,18 @@ of this software and associated documentation files (the "Software"), to deal
2525
import com.github.stephengold.joltjni.BodyCreationSettings;
2626
import com.github.stephengold.joltjni.BodyIdArray;
2727
import com.github.stephengold.joltjni.Jolt;
28+
import com.github.stephengold.joltjni.Mat44;
29+
import com.github.stephengold.joltjni.Mat44Array;
2830
import com.github.stephengold.joltjni.PhysicsSystem;
2931
import com.github.stephengold.joltjni.Quat;
3032
import com.github.stephengold.joltjni.RMat44;
33+
import com.github.stephengold.joltjni.RMat44Array;
3134
import com.github.stephengold.joltjni.RVec3;
3235
import com.github.stephengold.joltjni.ShapeRefC;
36+
import com.github.stephengold.joltjni.ShapeRefCArray;
3337
import com.github.stephengold.joltjni.SphereShape;
3438
import com.github.stephengold.joltjni.TransformedShape;
39+
import com.github.stephengold.joltjni.TransformedShapeArray;
3540
import com.github.stephengold.joltjni.Vec3;
3641
import com.github.stephengold.joltjni.enumerate.EActivation;
3742
import com.github.stephengold.joltjni.enumerate.EMotionType;
@@ -201,42 +206,61 @@ private void verifyLongGetters(
201206
}
202207

203208
// Verify Shapes
204-
ShapeRefC[] batchShapes = bi.getShapes(ids);
209+
ShapeRefCArray batchShapes = new ShapeRefCArray(n);
210+
bi.getShapes(ids, batchShapes);
205211
for (int i = 0; i < n; ++i) {
206212
ShapeRefC singularRef = bi.getShape(ids.get(i));
207-
Assert.assertEquals(
208-
singularRef.targetVa(), batchShapes[i].targetVa());
209-
TestUtils.testClose(singularRef, batchShapes[i]);
213+
ShapeRefC arrayRef = batchShapes.get(i);
214+
Assert.assertEquals(singularRef.targetVa(), arrayRef.targetVa());
215+
TestUtils.testClose(singularRef, arrayRef);
210216
}
217+
TestUtils.testClose(batchShapes);
211218

212219
// Verify TransformedShapes
213-
TransformedShape[] batchTs = bi.getTransformedShapes(ids);
220+
TransformedShapeArray batchTs = new TransformedShapeArray(n);
221+
bi.getTransformedShapes(ids, batchTs);
214222
for (int i = 0; i < n; ++i) {
215223
TransformedShape singularTs = bi.getTransformedShape(ids.get(i));
224+
TransformedShape arrayTs = batchTs.get(i);
216225
ConstShape s1 = singularTs.getShape();
217-
ConstShape s2 = batchTs[i].getShape();
226+
ConstShape s2 = arrayTs.getShape();
218227

219228
Assert.assertEquals(s1.targetVa(), s2.targetVa());
220-
TestUtils.testClose(s1, s2, singularTs, batchTs[i]);
229+
TestUtils.testClose(s1, s2, singularTs, arrayTs);
221230
}
231+
TestUtils.testClose(batchTs);
222232
}
223233

224234
/**
225-
* Verify batch matrix getters (COM transform).
235+
* Verify batch matrix getters (COM transform and inverse inertia).
226236
*
227237
* @param bi the interface to use (not null)
228238
* @param ids IDs of bodies to query (not null)
229239
* @param n the number of bodies
230240
*/
231241
private void verifyMatrixGetters(
232242
BatchBodyInterface bi, BodyIdArray ids, int n) {
233-
DoubleBuffer matBuf = Jolt.newDirectDoubleBuffer(n * 16);
234-
bi.getCenterOfMassTransforms(ids, matBuf);
243+
// Verify COM Transforms (Real precision)
244+
RMat44Array comBuf = new RMat44Array(n);
245+
bi.getCenterOfMassTransforms(ids, comBuf);
235246
for (int i = 0; i < n; ++i) {
236-
RMat44 m = bi.getCenterOfMassTransform(ids.get(i));
237-
Assert.assertEquals(m.getElement(0, 0), matBuf.get(i * 16), 1e-6);
238-
TestUtils.testClose(m);
247+
RMat44 singularM = bi.getCenterOfMassTransform(ids.get(i));
248+
RMat44 arrayM = comBuf.get(i);
249+
Assert.assertTrue(singularM.isEqual(arrayM));
250+
TestUtils.testClose(singularM, arrayM);
239251
}
252+
TestUtils.testClose(comBuf);
253+
254+
// Verify Inverse Inertias (Single precision)
255+
Mat44Array inertiaBuf = new Mat44Array(n);
256+
bi.getInverseInertias(ids, inertiaBuf);
257+
for (int i = 0; i < n; ++i) {
258+
Mat44 singularM = bi.getInverseInertia(ids.get(i));
259+
Mat44 arrayM = inertiaBuf.get(i);
260+
Assert.assertTrue(singularM.isEqual(arrayM));
261+
TestUtils.testClose(singularM, arrayM);
262+
}
263+
TestUtils.testClose(inertiaBuf);
240264
}
241265

242266
/**

0 commit comments

Comments
 (0)