Hi. I've been looking through the opcode 1.3 c++ source, which I obtained here: http://www.codercorner.com/Opcode.htm
, and comparing the MeshInterface class/struct with the MeshInterface class that's exposed to the Python API in Python-Ogre 1.6.1 (as documented in the included help file). I'm wondering why the mTris and mVerts members aren't exposed? Perhaps the automatic Python wrapper generation code is confused by the nested ifdef's in OPC_MeshInterface.cpp and OPC_MeshInterface.h.
It doesn't look like OPC_USE_CALLBACKS has been defined either, which makes the callback method of loading geometry data into opcode unusable as well.
Anybody know what's up with this library? Without at least one (working) method of loading data into the library, it would seem to be unusable...
I've looked at the opcode example in SVN (not included with the latest windows binary distribution of Python-Ogre), but it's written for an older version of opcode (1.2) and won't work with the newer opcode 1.3 version included with Python-Ogre 1.6.1.
The opcode wrapper was created quite a while back and never really used as it was kind-of replaced by the various physics libraries (ode, OgreNewt, bullet etc)...
There is a setCallback function on the Mesh interface if that's what you are looking for..
I'm happy to take fresh look at opcode if you are prepared to highlight whats missing and work with test code
Thanks Andy, I'll keep messing with it and see if I can get a proof of concept going at least
I don't really need a full physics library, just some basic collision detection. If there's some way to use those libraries for only collision detection without the overhead of a full physics simulation I'll definitely take a look. At the very least I need fast raycast tests against the actual mesh geometry, and possibly collision/penetration tests between convex meshes and an arbitrary (non-convex) mesh. I'm not even sure at this point if opcode will do what I want, but it initially looked promising
I can't find the "setCallback" function that you mentioned in the Python-Ogre docs (not in the Python-Ogre.chm file anyway). I'd prefer to use the pointer method described in OPC_MeshInterface.cpp, since it seems like it would be faster than using a per-triangle callback written in python:
* This class is an interface between us and user-defined meshes. Meshes can be defined in a lot of ways, and here we
* try to support most of them.
* Basically you have two options:
* - callbacks, if OPC_USE_CALLBACKS is defined in OPC_Settings.h.
* - else pointers.
* If using pointers, you can also use strides or not. Strides are used when OPC_USE_STRIDE is defined.
* Using callbacks is the most generic way to feed OPCODE with your meshes. Indeed, you just have to give
* access to three vertices at the end of the day. It's up to you to fetch them from your database, using
* whatever method you want. Hence your meshes can lie in system memory or AGP, be indexed or not, use 16
* or 32-bits indices, you can decompress them on-the-fly if needed, etc. On the other hand, a callback is
* called each time OPCODE needs access to a particular triangle, so there might be a slight overhead.
* To make things clear: geometry & topology are NOT stored in the collision system,
* in order to save some ram. So, when the system needs them to perform accurate intersection
* tests, you're requested to provide the triangle-vertices corresponding to a given face index.
* static void ColCallback(udword triangle_index, VertexPointers& triangle, udword user_data)
* // Get back Mesh0 or Mesh1 (you also can use 2 different callbacks)
* Mesh* MyMesh = (Mesh*)user_data;
* // Get correct triangle in the app-controlled database
* const Triangle* Tri = MyMesh->GetTriangle(triangle_index);
* // Setup pointers to vertices for the collision system
* triangle.Vertex = MyMesh->GetVertex(Tri->mVRef);
* triangle.Vertex = MyMesh->GetVertex(Tri->mVRef);
* triangle.Vertex = MyMesh->GetVertex(Tri->mVRef);
* // Setup callbacks
* MeshInterface0->SetCallback(ColCallback, udword(Mesh0));
* MeshInterface1->SetCallback(ColCallback, udword(Mesh1));
* Of course, you should make this callback as fast as possible. And you're also not supposed
* to modify the geometry *after* the collision trees have been built. The alternative was to
* store the geometry & topology in the collision system as well (as in RAPID) but we have found
* this approach to waste a lot of ram in many cases.
* If you're internally using the following canonical structures:
* - a vertex made of three 32-bits floating point values
* - a triangle made of three 32-bits integer vertex references
* ...then you may want to use pointers instead of callbacks. This is the same, except OPCODE will directly
* use provided pointers to access the topology and geometry, without using a callback. It might be faster,
* but probably not as safe. Pointers have been introduced in OPCODE 1.2.
* // Setup pointers
* MeshInterface0->SetPointers(Mesh0->GetFaces(), Mesh0->GetVerts());
* MeshInterface1->SetPointers(Mesh1->GetFaces(), Mesh1->GetVerts());
* If your vertices are D3D-like entities interleaving a position, a normal and/or texture coordinates
* (i.e. if your vertices are FVFs), you might want to use a vertex stride to skip extra data OPCODE
* doesn't need. Using a stride shouldn't be notably slower than not using it, but it might increase
* cache misses. Please also note that you *shouldn't* read from AGP or video-memory buffers !
* In any case, compilation flags are here to select callbacks/pointers/strides at compile time, so
* choose what's best for your application. All of this has been wrapped into this MeshInterface.
* \class MeshInterface
* \author Pierre Terdiman
* \version 1.3
* \date November, 27, 2002
But I'm not really sure to what extent the hardware buffers are consistent between different operating systems/APIs, and from what I'm seeing in the Python-Ogre help file it doesn't look like the stride support for opcode is enabled anyway, so I'm not really sure if that's viable. I guess I could construct another copy in memory with the correct format, but then I'd be storing the mesh data 3 times - one copy in video memory, one "shadowbuffer" copy in system memory, and another copy in system memory with the format that opcode is expecting. I might be misunderstanding something basic regarding the hardware buffers though, it's all pretty new to me
The opcode module was compiled with callbacks enabled so you don't have access to the pointers interface (it's an either/or situation).. This is also why mTris and mVerts don't exist as they are #def'ed out when callbacks are enabled...
And it's looks like the 'SetCallback' function for the mesh is NOT in the module -- I obviously started on it (it's partially done in code_generators/opcode/hand_made_wrappers.py) but didn't get it finished... I'll see if I can get it to work and put out an updated binary.....
You might also want to check out OgreBullet as it can be used a pure collisions module (OgreBulletC) -- documentation may also be lacking however it's a more 'active' module and more likely to get updates...
OK, I've been taking a look at OgreBullet. The example program that's provided doesn't quite work, but I managed to get it running (sort of) after making a few changes. Unfortunately, the program appears to initialize and then exit with no errors or warnings; it just quits all of a sudden.
I've tried to re-implement most of what was there in my own test app, but it also just suddenly terminates when it gets to a certain point. I've marked the offending line here:
# bullet physics world setup
bounds = ogre.AxisAlignedBox ((-100000, -100000, -100000),(100000, 100000, 100000))
self.world = bulletC.CollisionsWorld(sceneManager, bounds )
#self.world.ShowDebugShapes = True
# Setup the terrain
self.terrain = myTerrain(sceneManager)
# try to add bullet stuff to terrain
self.bulletObject = bulletC.Object("Terrain1", self.world, True)
# this line gives: TypeError: No Python class registered for C++ class class btCollisionObject
#print "self.bulletObject.getBulletObject()=", self.bulletObject.getBulletObject()
print "*** The program will now exit for no apparent reason!"
self.bulletObject.setShape ( self.terrain.collisionShape, self.terrain.node.position, self.terrain.node.Orientation)
print "*** You'll never see this message, since the previous line causes the program to terminate (!?)"
I'm not sure if this is being caused by something that I'm doing wrong or if there's a problem with the library. As I mentioned, the included bullet demo/sample also seems to exit abruptly in the same way (once you get it working). I've uploaded my entire test project here if anyone wants to have a look at it:
The lack of documentation and/or working examples for bullet is kind of brutal
Is there anybody out there using it who cares to share some example code?
Of course one "other" option is PhysX which does have a working demo and has great documentation (from Nvidia)..
I'll look at you sample code to see if I can determine what's happening..
Hey Andy, sorry to bother you again
I decided to build python-ogre from source in the hopes of attaching a debugger and tracking down the problem myself. I've gotten everything to build, with the exception of the bullet wrapper code
I'm using the python-ogre source from the "v1-6" branch (let me know if I should try trunk or not). Here's the tail end of the log:
F:\PythonOgre_build\bullet-2.73\src\LinearMath/btAlignedObjectArray.h(172) : error C2512: 'btDbvt::sStkNP::sStkNP' : no appropriate default constructor available
F:\PythonOgre_build\bullet-2.73\src\LinearMath/btAlignedObjectArray.h(123) : while compiling class template member function 'btAlignedObjectArray<T>::btAlignedObjectArray(const btAlignedObjectArray<T> &)'
f:\pythonogre_build\bullet-2.73\src\BulletCollision/BroadphaseCollision/btDbvt.h(1085) : see reference to class template instantiation 'btAlignedObjectArray<T>' being compiled
scons: building terminated because of errors.
02-18 21:13 PythonOgre.BuildModule DEBUG scons: *** [C:\temp\build_dir_2.5\bullet_2.73\AlignedObjectArrayDbvtsStkNP.pypp.obj] Error 2
Any help would be appreciated