Hey guys,
I noticed problems with raytesting & native bullet 2.82. It is because native bullet uses “gjk” raytesting by default, which apparently is a bit buggy. I notice it primarily when trying to raytest against large boxes. Anyway, the author of this change does offer a way to use the old raytesting method by settings some m_flags on the RayTestCallback object, see here:
https://code.google.com/p/bullet/source/detail?r=2686
It didn’t appear jMonkeyEngine3 provided access to m_flags to set the raytest method, so I added it to the bullet native’s PhysicsSpace.cpp file, like so:
[code] JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_rayTest_1native
(JNIEnv * env, jobject object, jobject from, jobject to, jlong spaceId, jobject resultlist, jint flags) {
jmePhysicsSpace* space = reinterpret_cast<jmePhysicsSpace*> (spaceId);
if (space == NULL) {
jclass newExc = env->FindClass("java/lang/NullPointerException");
env->ThrowNew(newExc, "The physics space does not exist.");
return;
}
struct AllRayResultCallback : public btCollisionWorld::RayResultCallback {
AllRayResultCallback(const btVector3& rayFromWorld, const btVector3 & rayToWorld) : m_rayFromWorld(rayFromWorld), m_rayToWorld(rayToWorld) {
}
jobject resultlist;
JNIEnv* env;
btVector3 m_rayFromWorld; //used to calculate hitPointWorld from hitFraction
btVector3 m_rayToWorld;
btVector3 m_hitNormalWorld;
btVector3 m_hitPointWorld;
virtual btScalar addSingleResult(btCollisionWorld::LocalRayResult& rayResult, bool normalInWorldSpace) {
if (normalInWorldSpace) {
m_hitNormalWorld = rayResult.m_hitNormalLocal;
} else {
m_hitNormalWorld = m_collisionObject->getWorldTransform().getBasis() * rayResult.m_hitNormalLocal;
}
m_hitPointWorld.setInterpolate3(m_rayFromWorld, m_rayToWorld, rayResult.m_hitFraction);
jmeBulletUtil::addResult(env, resultlist, m_hitNormalWorld, m_hitPointWorld, rayResult.m_hitFraction, rayResult.m_collisionObject);
return 1.f;
}
};
btVector3 native_to = btVector3();
jmeBulletUtil::convert(env, to, &native_to);
btVector3 native_from = btVector3();
jmeBulletUtil::convert(env, from, &native_from);
AllRayResultCallback resultCallback(native_from, native_to);
resultCallback.env = env;
resultCallback.resultlist = resultlist;
resultCallback.m_flags = flags;
space->getDynamicsWorld()->rayTest(native_from, native_to, resultCallback);
return;
}[/code]
Modified header:
[code]/*
- Class: com_jme3_bullet_PhysicsSpace
- Method: rayTest_native
- Signature: (Lcom/jme3/math/Vector3f;Lcom/jme3/math/Vector3f;JLjava/util/List;I)V
*/
JNIEXPORT void JNICALL Java_com_jme3_bullet_PhysicsSpace_rayTest_1native
(JNIEnv *, jobject, jobject, jobject, jlong, jobject, jint);[/code]
Made these changes to PhysicsSpace.java for bullet native:
[code] /**
* Sets m_flags for raytest, see https://code.google.com/p/bullet/source/browse/trunk/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
* for possible options. Defaults to using the faster, approximate raytest.
*/
public void SetRayTestFlags(int flags) {
rayTestFlags = flags;
}
/**
* Gets m_flags for raytest, see https://code.google.com/p/bullet/source/browse/trunk/src/BulletCollision/NarrowPhaseCollision/btRaycastCallback.h
* for possible options.
* @return rayTestFlags
*/
public int GetRayTestFlags() {
return rayTestFlags;
}
/**
* Performs a ray collision test and returns the results as a list of
* PhysicsRayTestResults
*/
public List<PhysicsRayTestResult> rayTest(Vector3f from, Vector3f to, List<PhysicsRayTestResult> results) {
results.clear();
rayTest_native(from, to, physicsSpaceId, results, rayTestFlags);
return results;
}
public native void rayTest_native(Vector3f from, Vector3f to, long physicsSpaceId, List<PhysicsRayTestResult> results, int flags);[/code]
rayTestFlags just being a private int = 4 (defaulting to using the simple raytest that worked better for me)
Anyway, this does work on my Linux 64 machine, because I can successfully build those native bullet binaries. However, I’m having trouble getting the mingw32 / Windows builds to work… I can also build the Mac version with these improvements. I may need help from someone to build the Windows 32-bit version, then we can get this problem solved…
Thank you,
- Phr00t