PhysX Concerns/Complications

Brad

26-07-2008 14:40:53

I recently decided to make a move from a standalone setup of pyODE (that I had abstractly binded to a generic render wrapper [subsequently linked to python-Ogre]) to python-ogre's package-integrated (but "standalone") package of PhysX. Disappointingly, several issues have come up.

The first problem arose when attempting to import PhysX by itself. Despite the folders being neatly tucked away independently, I quickly encountered some DLL mishaps that were easily squashed by my [b][u]previous post's solutions[/u][/b] that Andy had given. Additionally and strangely enough, even though PhysX is labeled in more recent versions as a standalone package, the __init__ import stage of the PhysX folder still imports Ogre itself (for what appears to be a typecasting class between Quaternions on the two). After removing this portion, the import still seems to function correctly, although I'm not certain that capability wasn't compromised.

After successfully importing the PhysX library, my first tests involved creating a simple physics environment to attach several bodies within. Following the PhysX API I had, I quickly ran through and found the basic methods/classes I'd need to use to setup a scene and set the gravity.

import ogre.physics.PhysX as physics
scene = physics.NxScene()
scene.setGravity((0.0,-9,8,0.0))

The last command produces an error. No problem. I can understand that all vector types in all libraries that python-ogre offers haven't been fully adapted to a shorthand method accustomed to python itself.

A quick glimpse and I find what's needed.

import ogre.physics.PhysX as physics
scene = physics.NxScene()
scene.setGravity(physics.NxVec3(0.0,-9.8,0.0))

This is where things start to get sticky. PhysX expects a native NxVec3 as a parameter here, however, issuing the command as so produces :

Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
scene.setGravity(physics.NxVec3(0.0,-9.8,0.0))
RuntimeError: Pure virtual function called

Perhaps I've misunderstood the syntax or I'm doing something wrong so I then decide to just directly load up one of the C++ demo examples of PhysX and convert it over to be sure at least one approach I have is proper.

I'm no C++ programmer by any means, but from what I can tell of the samples is that the generally accepted process of PhysX is to create instances of "Desc" (assumably describers or descriptions) classes and then pass these instances in to create the actual instances of said classes. It's a bit different than directly passing parameters to a create method, but again, no big deal. Here I notice they've instanced a NxPhysicsSDK class and used it to generate the scene from another Desc base.

Fair enough.

gPhysicsSDK = NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, NULL, new ErrorStream(), desc, &errorCode);
Since I cannot seem to find some of the constants they need, I decide to directly instance this class as well. So far so good. Everything seems to go find until the point where I actually instance the scene itself.

import ogre.physics.PhysX as physics
SDK = physics.NxPhysicsSDK()
sceneBase = physics.NxSceneDesc()
sceneBase.gravity = physics.NxVec3(0.0,-9.8,0.0)
scene = SDK.createScene(sceneBase)

Once again I run into another pure virtual function called error. Seems to occur when passing an instance of one of their classes as a parameter for construction to another instance.

Perhaps I'm going all about it in the wrong way, but my luck has been minimal (at best) on various other approaches as well. I didn't see any direct PhysX examples in the python-ogre installation and the NxOgre ones seemed to indicate that NxOgre itself was pretty abstracted beyond the standard PhysX syntax.

I wouldn't mind to convert some of the C++ samples provided with the PhysX SDK. I really just need at least some solid foundation of capable commands that don't produce errors. I've tried a couple of other scene and SDK instancing approaches, but eventually I run into a similar error-set.

Again though, these could just be related to my own blunder of misunderstanding the syntax needed by PhysX. The direct instancing of the classes could be one of my downfalls, but I've yet to come across alternate methods where all certain library constants I need are available so that I may use another approach.

----------

Overall, my goal is just to find a python-binded physic's library (besides PyODE) that doesn't have reliance on Ogre. The reasoning for this is pretty simple. I have rendering/physics abstracted in my development group's engine to matters beyond just relying on a concrete rendering or physics library, so using libraries that aren't restricted as binding to a particular sub-concept are a must.

Although I know it's probably beyond grasp at the moment, I think it might be beneficial to the python-ogre development team if libraries that didn't have python-ogre dependency were made separately available as unique packages so that those looking for such libraries for Python itself could be found. This would make most sense especially in the case that (if I remember correctly) python-ogre also wanted to abstract out it's various rendering (and other) concepts to those beyond just Ogre.

I realize, however, that Andy is one of the few working actively on python-ogre. Maintaining independent Python libraries probably would not be possible within time availability constraints.

Alternatively, I've seen partial half-started bindings of pyNewt and pyBullet floating around here and there, but nothing actually fleshed out enough for a development environment. However, If anyone has solutions to any other python-binded libraries aside from pyODE, I'd be keen on listening.

andy

27-07-2008 01:09:32

The simple answer to your problems is the fact that no one has had the time to write demos for Physx to then see what was broken.

And I'm excited that you are interested in using the library and will happily look at any issues you have and resolve them (as I'd really like to have a stable, functionaly wrapper for PhysX)...

Can you switch to using the google mailing list and I'll work with you there to fix the wrapper..

Regards

Andy

saladin

10-10-2008 05:23:50

The simple answer to your problems is the fact that no one has had the time to write demos for Physx to then see what was broken.

And I'm excited that you are interested in using the library and will happily look at any issues you have and resolve them (as I'd really like to have a stable, functionaly wrapper for PhysX)...

Can you switch to using the google mailing list and I'll work with you there to fix the wrapper..

Regards

Andy


I'd like to second Brad opinion on standalone python wrapping for some librarys. I can understand why ogreAL is wrapped instead of openAL cuz it's straightforward and we don't really have an alternative when it comes to sound module. However physics to me belongs to control layer. I'd like to keep control and view separate.

A working python PhysX wrapper will help immensely for our current project. So I'm really looking forward to it.

andy

10-10-2008 08:40:27

Is there a particular issue you have with the PyhsicX wrapper that needs to be resolved?

I believe the current verison is pretty good AND that you will need to spend some time with the PyhsicX documentation to understand how best to use the library.

As mentioned, if you find specific issues I'm more than happy to work on them in near real time -- and the best place to do this is the Google mailing list :)

Regards
Andy

dermont

21-10-2008 05:27:39


I believe the current verison is pretty good AND that you will need to spend some time with the PyhsicX documentation to understand how best to use the library.


I'm guessing from the above that this works fine on Windows. However for me on on Linux I'm having problems creating even a simple example.

a) The build fails when creating the doc strings for NxTireFunctionDesc:

build output:

generated/physx_2.8.1/NxTireFunctionDesc.pypp.cpp: In function ‘void register_NxTireFunctionDesc_class()’:
generated/physx_2.8.1/NxTireFunctionDesc.pypp.cpp:60: error: unknown escape sequence: '\040'
generated/physx_2.8.1/NxTireFunctionDesc.pypp.cpp:60: error: unknown escape sequence '\~'


generated file:

typedef bp::class_< NxTireFunctionDesc_wrapper > NxTireFunctionDesc_exposer_t;
NxTireFunctionDesc_exposer_t NxTireFunctionDesc_exposer = NxTireFunctionDesc_exposer_t( "NxTireFunctionDesc", "Force\n\
^ extremum\n\
| __\n\
| ~ \ asymptote\n\
| \~________________\n\
| \n\
|\n\
--------------------------. Slip\n\
\n" );
bp::scope NxTireFunctionDesc_scope( NxTireFunctionDesc_exposer );
NxTireFunctionDesc_exposer.def( bp::init< >() );


b) The simplest demo segfaults trying to create a NxCreatePhysicsSDK. I've tried setting the suggested linux defines for PhysX in generate_code and environment.py, preloading the PhysX libraries such as libPhysXLoader.so with the same results.

test.py

NX_SDK_VERSION_MAJOR = 2
NX_SDK_VERSION_MINOR = 8
NX_SDK_VERSION_BUGFIX = 1

import _physx_ as physx
NX_PHYSICS_SDK_VERSION = (NX_SDK_VERSION_MAJOR<<24)+(NX_SDK_VERSION_MINOR<<16)+(NX_SDK_VERSION_BUGFIX<<8) + 0
print NX_PHYSICS_SDK_VERSION
gPhysicsSDK = physx.NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION )
print dir(gPhysicsSDK)
gPhysicsSDK.release()


>> python test.py
34078976
Segmentation fault

backtrace:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0xb7d2e8c0 (LWP 17875)]
0xb5e4655d in __dynamic_cast () from /usr/lib/libstdc++.so.6
(gdb) bt
#0 0xb5e4655d in __dynamic_cast () from /usr/lib/libstdc++.so.6
#1 0xb7820708 in boost::python::objects::caller_py_function_impl<boost::python::detail::caller<NxPhysicsSDK* (*)(unsigned int, NxUserAllocator*, NxUserOutputStream*, NxPhysicsSDKDesc const&, NxSDKCreateError*), boost::python::return_value_policy<boost::python::reference_existing_object, boost::python::default_call_policies>, boost::mpl::vector6<NxPhysicsSDK*, unsigned int, NxUserAllocator*, NxUserOutputStream*, NxPhysicsSDKDesc const&, NxSDKCreateError*> > >::operator() ()
from /media/sda1/Development/PYTHONOGRE/python-ogre-rc1/packages_2.5/ogre/physics/PhysX/_physx_.so
#2 0xb5d6a322 in boost::python::objects::function::call ()
from /usr/local/lib/libboost_python-gcc42-mt-1_36.so.1.36.0
#3 0xb5d6a527 in ?? ()
from /usr/local/lib/libboost_python-gcc42-mt-1_36.so.1.36.0
#4 0xb5d7168b in boost::function0<void>::operator() ()
from /usr/local/lib/libboost_python-gcc42-mt-1_36.so.1.36.0
#5 0xb5d7071e in boost::python::handle_exception_impl ()
from /usr/local/lib/libboost_python-gcc42-mt-1_36.so.1.36.0
#6 0xb5d6747e in ?? ()
from /usr/local/lib/libboost_python-gcc42-mt-1_36.so.1.36.0
#7 0x0805cb37 in PyObject_Call (func=0xf8, arg=0xb52f71cc, kw=0x0)
at ../Objects/abstract.c:1861
#8 0x080c7987 in PyEval_EvalFrameEx (f=0x8191b54, throwflag=0)
---Type <return> to continue, or q <return> to quit---
at ../Python/ceval.c:3784
#9 0x080cb0d7 in PyEval_EvalCodeEx (co=0xb7cb8a88, globals=0xb7d07acc,
locals=0xb7d07acc, args=0x0, argcount=0, kws=0x0, kwcount=0, defs=0x0,
defcount=0, closure=0x0) at ../Python/ceval.c:2836
#10 0x080cb227 in PyEval_EvalCode (co=0xb7cb8a88, globals=0xb7d07acc,
locals=0xb7d07acc) at ../Python/ceval.c:494
#11 0x080ea6d8 in PyRun_FileExFlags (fp=0x816b008,
filename=0xbfeb9732 "test1.py", start=257, globals=0xb7d07acc,
locals=0xb7d07acc, closeit=1, flags=0xbfeb83c8)
at ../Python/pythonrun.c:1273
#12 0x080ea979 in PyRun_SimpleFileExFlags (fp=0x816b008,
filename=0xbfeb9732 "test1.py", closeit=1, flags=0xbfeb83c8)
at ../Python/pythonrun.c:879
#13 0x08059335 in Py_Main (argc=1, argv=0xbfeb8494) at ../Modules/main.c:523
#14 0x080587f2 in main (argc=Cannot access memory at address 0xf8
) at ../Modules/python.c:23


c) Even trying to create a user supplied interface for reporting errors for NxCreatePhysicsSDK isn't possible since python balks on NxUserOutputStream's virtual "print" method.


class ErrorStream(physx.NxUserOutputStream):
def __init__(self):
physx.NxUserOutputStream.__init__(self)

def reportError(self, e, message, mfile, line):
pass
def reportAssertViolation(self,message, mfile, line):
pass

def print(self, message):
print message

es = ErrorStream()
gPhysicsSDK = physx.NxCreatePhysicsSDK(NX_PHYSICS_SDK_VERSION, ..., es,... )

smb

22-11-2008 18:56:33

1. There is no interface to add shapes to actors :(
actorDesc.shapes.pushBack(sphereDesc)
TypeError: No Python class registered for C++ class class NxArray<class NxShapeDesc *,class NxAllocatorDefault>
2. How can I use NxScene.getActiveTransforms()?

andy

23-11-2008 03:30:16

Glad to see people starting to use this wrapper -- and hence happy to help improve it further....

#1 - Some of the NxArray classes were intentional excluded as the wrapper code didn't compile -- I've looked at it again and turns out to be a simple fix (removed the default constructor) so now they are included and the code compiles -- however haven't tested this at all so any test code you have would be appreciated.

#2 - lots (111 to be exact) functions require transformation (ie tweaked so you can use them with Python) however are "Pure Virtual" which we currently can't do automatically with Py++. I'll take a look to see if I can auto-magically hand wrap these functions much like I'm doing with some of the 'get' functions..

If you are building from SVN you can try the #1 fix now, otherwise give me some time to put out a newer Physx module.

regards
Andy

smb

23-11-2008 12:14:00

I'll try svn version next month. Is there a way to checkout only physx wrapper sources and the build scripts? I have a strictly limited internet :(

performance-offtopic: I had 20 fps in hydrax demo. Where is the bottleneck, python or hydrax?

bharling

23-11-2008 17:44:00

I'd say Hydrax, having tried both the c++ demo and the python-ogre version performance is about the same ( maybe 1fps is dropped in python, but that would be expected )

dermont

26-11-2008 12:07:21

How did you resolve the gccxml/assembly code issue with Visual Studio 2008 which causes the code generation of the physx module to fail.


...
c:/program files/NVIDIA Corporation/NVIDIA Physx SDK/v2.8.1/SDKs/Foundation/incl
ude/NxMath.h:744: error: '_asm' was not declared in this scope
c:/program files/NVIDIA Corporation/NVIDIA Physx SDK/v2.8.1/SDKs/Foundation/incl
ude/NxMath.h:744: error: expected `;' before 'fld'



From environment.py there appears to be a reference to the above problem.

CCFLAGS = ' -D"WIN32" '
## CCFLAGS = ' ' ## try to not define WIN 32 to remove inline assembly code that GCCxml doesn't like

andy

26-11-2008 13:10:04

Damm -- know i'd forget something...

Basically I commented out the entire section by doing the following:
#ifdef WIN32_1
NxF32 localCos, localSin;
NxF32 local = f;
_asm fld local
_asm fsincos
_asm fstp localCos
_asm fstp localSin
c = localCos;
s = localSin;
#else
c = cosf(f);
s = sinf(f);
#endif


However, since that time I've added a '__PYTHONOGRE_BUILD_CODE' to the define list to handle these types of issues so I'd tend to patch it with a

#ifdef WIN32 && !(defined __PYTHONOGRE_BUILD_CODE)
I'll add this as a patch to the overall build process..

Andy

dermont

26-11-2008 13:32:54

Thanks I did consider something similar to the above but wasn't sure if this would be violating the NVIDIA PhysX End User License Agreement.

I'll add this as a patch to the overall build process..


Before doing so I would read the EULA for clarification, 2.(i) states for example:

In addition, you may not and shall not permit others to:
(i) modify, reproduce, de-compile, reverse engineer or translate the PhysX
SDK;

andy

26-11-2008 14:15:31

I think there is a level of reasonableness involved here -- however I will let Nvidia know via my development registration..

Andy

dermont

05-12-2008 10:11:14

I seem to be having problems with methods that return an array of pointers such as scene.getActors() and actor.getShapes().

Errors returned are in the form:

TypeError: No to_python (by-value) converter found for C++ type: class NxActor


This following crashes on getActors() / getShapes() :

import sys
sys.path.insert(0,'..')
import PythonOgreConfig

import ogre.physics.PhysX as physx
import SampleFramework as sf
from math import *


gphysxSDK,errorCode = physx.NxCreatePhysicsSDK(physx.NX_PHYSICS_SDK_VERSION())
if (errorCode!=physx.NXCE_NO_ERROR):
print "\nSDK create error (%d - %s).\nUnable to initialize the PhysX SDK, exiting the sample.\n\n" % (errorCode,"test")
sys.exit(1)
gphysxSDK = physx.NxGetPhysicsSDK()

# Set the physx parameters
gphysxSDK.setParameter(physx.NX_SKIN_WIDTH, -0.01)

# Set the debug visualization parameters
gphysxSDK.setParameter(physx.NX_VISUALIZATION_SCALE, 1)
gphysxSDK.setParameter(physx.NX_VISUALIZE_COLLISION_SHAPES, 1)
gphysxSDK.setParameter(physx.NX_VISUALIZE_JOINT_LIMITS, 1)
gphysxSDK.setParameter(physx.NX_VISUALIZE_JOINT_LOCAL_AXES, 1)

sceneDesc = physx.NxSceneDesc()
sceneDesc.gravity = physx.NxVec3(0.0,-9.8,0.0)
gScene = gphysxSDK.createScene(sceneDesc)

print dir(gScene)
# Create the default material
m = physx.NxMaterialDesc ()
m.restitution = 0.5
m.staticFriction = 0.2
m.dynamicFriction = 0.2
mat = gScene.getMaterialFromIndex(0)
mat.loadFromDesc(m)

shapeDimensions = physx.NxVec3( 100, 100, 100 )
# box shape description
boxShapeDesc = physx.NxBoxShapeDesc()
boxShapeDesc.dimensions = shapeDimensions
boxShapeDesc.density = 200

# actor description
actorDesc = physx.NxActorDesc()
actorDesc.shapes.pushBack(boxShapeDesc)
actorDesc.density = 200

actor = gScene.createActor(actorDesc)

print dir(actor)
print "Number Actors %d" % ( gScene.getNbActors() ) # 1
print "Number Shapes %d" % ( actor.getNbShapes() ) # 1

# TypeError: No to_python (by-value) converter found for C++ type: class NxActor
#print dir( gScene.getActors() )

print dir( actor.getShapes() )
#TypeError: No to_python (by-value) converter found for C++ type: class NxShape


gScene.releaseActor(actor)
gphysxSDK.releaseScene(gScene)
physx.NxReleasePhysicsSDK(gphysxSDK)


Using latest svn python ogre / ogre1.6.0 (no threading) / boost-python 1.37 / visual studio 2008.

dermont

14-12-2008 10:00:58

It appears that most of the samples included with PhysX use the MemoryWriteBuffer and MemoryReadBuffer classes.
These are not part of the SDK but are include as part of the samples common source code, i.e Samples\SampleCommonCode\src Stream.cpp/ Stream.h.
I'm using a modified version of MemoryWriteBuffer/MemoryReadBuffer and it appears to work OK.

Shouldn't something similar not be included as part of the bindings?

dermont

14-12-2008 10:28:44

How do I set the points / triangles for classes such as NxTriangleMeshDesc and NxConvexMeshDesc?. Is there some ctypes magic that I should be applying?


meshDesc = physx.NxTriangleMeshDesc()
meshDesc.setToDefault()
...
meshDesc.points = vertices
meshDesc.triangles = indices
...


Currently as a workaround I've added helper functions for setPoints and setFaces (for NxSimpleTriangleMesh) to accept a python list of NxVec3's / ints, e.g:


WRAPPER_DEFINITION_NxSimpleTriangleMesh = \
"""
void NxSimpleTriangleMesh_setPoints(::NxSimpleTriangleMesh& me,boost::python::list vertices, unsigned int vertex_count ){

unsigned int index;
::NxVec3* verts = new NxVec3[vertex_count];
for (index =0 ; index < vertex_count ; index ++) {
verts[index] = bp::extract<::NxVec3> (vertices[index]);
}
me.points = verts;
}
void NxSimpleTriangleMesh_setFaces(::NxSimpleTriangleMesh& me,boost::python::list faces, unsigned int face_count ) {
unsigned int index;
::NxU32* triangles = new NxU32[face_count];
for (index =0 ; index < face_count ; index ++) {
triangles[index] = (::NxU32)(bp::extract<float> (faces[index]));
}
me.triangles = triangles;
}
"""

WRAPPER_REGISTRATION_NxSimpleTriangleMesh = [
"""def( "setPoints", &::NxSimpleTriangleMesh_setPoints,
( bp::arg("vertices"), bp::arg("vertex_count")),
"Python-Ogre Hand Wrapped\\nSet's the points for a SimpleTriangleMesh",
bp::return_value_policy< bp::reference_existing_object, bp::default_call_policies >());""",
"""def( "setFaces", &::NxSimpleTriangleMesh_setFaces,
( bp::arg("faces"), bp::arg("face_count")),
"Python-Ogre Hand Wrapped\\nSet's the faces for a SimpleTriangleMesh",
bp::return_value_policy< bp::reference_existing_object, bp::default_call_policies >());""",

]


and in code:

meshDesc = physx.NxTriangleMeshDesc()
meshDesc.setToDefault()
meshDesc.numVertices = len(vertices)
meshDesc.pointStrideBytes = CMathUtilities.getSizeofNxVec3()
meshDesc.setPoints(vertices, len(vertices))

meshDesc.numTriangles = int(len(indices)/3)
meshDesc.triangleStrideBytes = 3*CMathUtilities.getSizeofNxU32()
meshDesc.setFaces(indices, len(indices))

andy

14-12-2008 23:32:31

I'll take a further look at this -- points and triangles are exposed however it seems Py++ exposed them as readonly attributes which doesn't help - this may be because the underlying C++ code defines them as 'const' ??

Anyway if I can't work this out I'll use your wrapper code :)

Thanks
Andy

dermont

15-12-2008 06:17:46

Yes you are correct they are exposed as readonly attributes, as are other properties such as NxActor::userData. So the the above wrapper code probably isn't of much use.

Did you see the comments regarding the MemoryWriteBuffer and MemoryReadBuffer classes on the previous page.

andy

18-12-2008 12:37:45

Dermont

Thanks for the wrapper code -- it's now in the SVN -- also I've made significant changes to how pure virtual functions are handled (when there is a transformation required) and we've added a setter to the ctypes property exposing in Py++..

So if you get a chance update to the latest Py++ and Python-Ogre and try a new PhysX build...

Regards
Andy

dermont

18-12-2008 16:47:35

Ok I'll try a new PhysX build when I get a chance. A couple of points:

1) Will the updates resolve the problems with returning arrays such as actor.getShapes()? Updating the "PointerDec=\" hand wrapped code to something like this resolved the problem previously:

PointerDec=\

for (index=0;index<size;index++ ) {
+ outlist.append ( boost::python::object( boost::ref(*Var_%(function_name)s++)) );
- outlist.append ( *Var_%(function_name)s++ );
}



2) There appears to be no way to cast shapes/ joints to their derived classes, e.g.


hingeDesc = physx.NxRevoluteJointDesc()
joint = self.physXManager.getNxScene().createJoint(hingeDesc)
print type(joint) # returns type as NxJoint not NxRevoluteJointDesc

for s in actor.getShapes():
type(s) # always returns NxShape
etc.


What is the best way to automatically implement dynamic_casting to handle the above. One way would be something like the following, is there an easier way?


baseClasses = ["::NxShape", "::NxJoint"]
for c in baseClasses:
v = global_ns.class_(c)
for b in v._derived:
classToCast = b.related_class.name
print classToCast
#function_dynamic_cast(c, classToCast)


3) After I rebuild PhysX I'll submit the simple sample I'm using.

andy

18-12-2008 23:29:59

Would be great to see the sample -- and no I don't expect that the issues you've mentioned above are resolved as I wasn't aware of them :)

Will take a look today

regards
Andy

dermont

19-12-2008 04:38:26


  1. 1. The problem was raised 2 weeks ago, see page 1 of this thread for an
    example. Updating PointerDec as indicated above worked for me.
    2. I only just became aware of the problem when implementing joints.
    3. A test example is in the tracker. It uses OgreOde DebugObject so you will
    need to add the OgreOde media dir to resources.cfg to run.
    [/list:u]
    I'll try out the ctypes setter properties for TriangleMeshes.

dermont

20-12-2008 14:53:46

Ok I've updated to latest version of py++ - rev 1478. There appears to be differences in the versions of the boost indexing suite supplied with python ogre and py++, namely the includes, e.g:

pythonogre
#include <boost/python/suite/indexing/container_traits.hpp>
py++
#include <indexing_suite/container_traits.hpp>

The generated header code for the ogre module is in following form and the build fails (using boost built with the indexing suite from python ogre) since it can't find the headers.

#include "python_ogre_precompiled.h"
#include "boost/python.hpp"
#include "indexing_suite/container_suite.hpp"
#include "indexing_suite/vector.hpp"
#include "poselist.pypp.hpp"


Obviously something has been updated that I've missed. There are a number of ways to resolve the above but what version of the indexing suite should I now be using?

andy

21-12-2008 00:38:29

Sorry - Py++ has implemented the indexing suite a headers so it doesn't require any linking etc into existing boost libraries..

Copy pyplusplus\indexing_suite_V2\indexing_suite to your 'Boost' directory and you should be fine...

However, it may require that you go back to a standard boost build without the current Python-Ogre indexing suite as part of it incase you get overlapping name spaces etc..

I'm using the standard Boost 1.37 (built without any changes) and then moved the indexing_suite directory into the boost_1_37_0 one..

Andy

dermont

21-12-2008 12:22:55

Thanks, that solved my build issues.

dermont

02-01-2009 07:48:55

dermont wrote:
There appears to be no way to cast shapes/ joints to their derived classes, e.g.
I should I have read the apis more closely, you can do it via the "Is... Shape/Joint Type", for example:

s = shape.isBox()
j = joint.isRevoluteJoint()


Andy wrote:
we've added a setter to the ctypes property exposing in Py++
Ok I've tried this out, just wan't to confirm that for NxTriangleMeshDesc points I should be setting the address of the first element of the array:

class POINT(ctypes.Structure):
_fields_ = ("x", ctypes.c_float), ("y", ctypes.c_float), ("z", ctypes.c_float)

self.pts = (POINT * 3)(*( [POINT(1.0,2.0,3.0), POINT(4.0,5.0,6.0), POINT(7.0,8.0,9.0)] ))
meshDesc = physx.NxTriangleMeshDesc()
meshDesc.setToDefault()
meshDesc.numVertices = len(self.pts)
meshDesc.pointStrideBytes = ctypes.sizeof(POINT)
meshDesc.points = ctypes.addressof(self.pts[0]) #Pointer to first triangle

andy

03-01-2009 02:28:40

I've not used ctypes.structure before so don't know if the approach you are taking will work or not...

In Demo_Bezier I used a flat array
storageclass = ctypes.c_float * (9)
points=storageclass(1.1)
## Patch data
points[0]=1.0
points[1] = 2.0
# etc
.....
meshDesc.points = ctypes.addressof(points)


However your approach is more readable and something I should use in the demos (I think)..

Regards
Andy

dermont

16-02-2009 08:35:14

Is there something wrong with the suggested update, mentioned in a previous thread, for resolving the problem for returning arrays such as actor.getShapes()?

Index: hand_made_wrappers.py
===================================================================
--- hand_made_wrappers.py (revision 888)
+++ hand_made_wrappers.py (working copy)
@@ -298,7 +298,7 @@
%(returnbase)s * Var_%(function_name)s = me.%(function_name)s();

for (index=0;index<size;index++ ) {
- outlist.append ( *Var_%(function_name)s++ );
+ outlist.append ( boost::python::object( boost::ref(*Var_%(function_name)s++)) );
}
return outlist;
}

Tom

18-02-2009 09:06:50

I actually was working on this a few months back and managed to get a few things working that either weren't binded or weren't binded correctly. I didn't post my work because I really hadn't done that much. Just enough to get a basic box demo completed. Seeing as I was horrible with py++ I editted the generated cpp files myself sometimes. To get any of the get(Shapes,Actors,etc..) functions working I had to change my handmade wrapper for PointerDec=\ to


boost::python::list
%(classname)s_%(function_name)s( %(classname)s & me ) {
boost::python::list outlist;
int index;
int size = (int)me.%(getsizefunction)s();
%(returnbase)s * Var_%(function_name)s = me.%(function_name)s();

for (index=0;index<size;index++ ) {
outlist.append ( boost::ref(*Var_%(function_name)s) );
*Var_%(function_name)s++;
}
return outlist;
}


I also made it so you could use NxVec3 and NxQuat as tuples (like ogre). I basically just copied the way Andy did it for Ogre :P
I'm not sure if this has been done in the current version, but here is the cpp and hpp code, just put the file in code_generators\physx and make sure the file gets added to the generated files.

CPP

#include "python_physx.h"
#include "boost/python/object.hpp" //len function
#include "boost/python/ssize_t.hpp" //ssize_t type definition
#include "boost/python/detail/none.hpp"
#include "tuples.hpp"
#include "custom_rvalue.pypp.hpp"

namespace bpl = boost::python;



typedef NxReal real_type;
typedef NxVec3 vector_type;
typedef NxQuat quat_type;

struct PyTuple2Vector3{

typedef boost::tuples::tuple< real_type, real_type, real_type> vector_tuple_type;

typedef bpl::from_py_sequence< vector_tuple_type > converter_type;

static void* convertible(PyObject* obj){
return converter_type::convertible( obj );
}

static void
construct( PyObject* obj, bpl::converter::rvalue_from_python_stage1_data* data){

typedef bpl::converter::rvalue_from_python_storage<vector_type> vector_storage_t;
vector_storage_t* the_storage = reinterpret_cast<vector_storage_t*>( data );
void* memory_chunk = the_storage->storage.bytes;

real_type x(0.0), y(0.0), z(0.0);
boost::tuples::tie(x, y, z) = converter_type::to_c_tuple( obj );

vector_type* vec = new (memory_chunk) vector_type(x, y, z);
data->convertible = memory_chunk;
}
};

struct PyTuple2Quaternion{

typedef boost::tuples::tuple< real_type, real_type, real_type, real_type> quat_tuple_type;

typedef bpl::from_py_sequence< quat_tuple_type > converter_type;

static void* convertible(PyObject* obj){
return converter_type::convertible( obj );
}

static void
construct( PyObject* obj, bpl::converter::rvalue_from_python_stage1_data* data){

typedef bpl::converter::rvalue_from_python_storage<quat_type> quat_storage_t;
quat_storage_t* the_storage = reinterpret_cast<quat_storage_t*>( data );
void* memory_chunk = the_storage->storage.bytes;

real_type fW(0.0), fX(0.0), fY(0.0), fZ(0.0);
boost::tuples::tie(fW, fX, fY, fZ) = converter_type::to_c_tuple( obj );

quat_type* quat = new (memory_chunk) quat_type(fW, vector_type(fX, fY, fZ));
data->convertible = memory_chunk;
}
};

void r_values_impl::register_pytuple_to_vector3_conversion(){
bpl::converter::registry::push_back( &::PyTuple2Vector3::convertible
, &::PyTuple2Vector3::construct
, bpl::type_id<vector_type>() );
}

void r_values_impl::register_pytuple_to_quaternion_conversion(){
bpl::converter::registry::push_back( &::PyTuple2Quaternion::convertible
, &::PyTuple2Quaternion::construct
, bpl::type_id<quat_type>() );
}


HPP


// This file has been generated by Py++.

#ifndef custom_rvalue_hpp__pyplusplus_wrapper
#define custom_rvalue_hpp__pyplusplus_wrapper

namespace r_values_impl{

void register_pytuple_to_vector3_conversion();

void register_pytuple_to_quaternion_conversion();

}

#endif//custom_rvalue_hpp__pyplusplus_wrapper


If you want you can include tuples.hpp as well (I believe that's what Andy did for the ogre bindings).

I think the stuff that I directly changed in the generated files were for NxUserContactReport, NxContactPair and NxContactStreamIterator. I'm not that great with py++ so if you want I can just post my code for the generated files. I remember NxUserContactReport was a pain to get working correctly.
You can check the docs to see how to create a UserContactReport, but this is basically how I got it working in python:


sceneBase = physx.NxSceneDesc()
sceneBase.gravity = (0.0,-9.810*100,0.0)
self.contactReport = physx.NxUserContactReport()
#note you must make your own function and override it with the contactReport's
self.contactReport.onContactNotify = self.onContactNotify
sceneBase.userContactReport = self.contactReport
#then the function
def onContactNotify(self,pair,events):
#do whatever you want here when two object collide


Here is a more practical onContactNotify use:


#note this function gets sent a contactPair and events
def onContactNotify(self,pair,events):
#iterate through the pair
iterator = pair.getContactIterator()
while(iterator.goNextPair()):
while(iterator.goNextPatch()):
while(iterator.goNextPoint()):
normal = iterator.getPatchNormal()
point = iterator.getPoint()
#print the contact normal and point
print "normal", normal.x,normal.y,normal.z
print "point", point.x,point.y,point.z


Also I'm not sure how you're initializing the SDK object. I had troubles at first with it, here is how I do it:


SDKDesc = physx.NxPhysicsSDKDesc()
#don't need to use this option
SDKDesc.flags = physx.NxSDKCreationFlag.NX_SDKF_NO_HARDWARE
self.physxSDK = physx.NxCreatePhysicsSDK(physx.NX_PHYSICS_SDK_VERSION,None,None,SDKDesc)

The ONLY way I could get it to create the sdk object is by defining NX_PHYSICS_SDK_VERSION as 0x02080100 (as they do in the sdk). I just defined this in the modules __init__.py in site packages to make it easy to access. This isn't the best way to do it however, since it'll only work for version 2.8.1 of the PhysX SDK
I think that about covers everything I did. As much as I'd like to help further I've been pretty busy lately :/ Hope this helps!

dermont

18-02-2009 10:18:27

I believe the above patch for "PointerDec=\" has already been applied to svn.

The NX_PHYSICS_SDK_VERSION problem has already been resolved, you can for example initialise the SDK with:

gphysxSDK,errorCode = physx.NxCreatePhysicsSDK(physx.NX_PHYSICS_SDK_VERSION())


There's a "sandbox" demo here with hasn't been updated for Shapes,Actors lists but instead uses some ugly workarounds. Maybe you would like to incorporate (or update to) your demo here.
http://python-ogre.svn.sourceforge.net/ ... iew=markup

As for the rest of your changes you could submit a patch at the following link. I'm sure Andy would be greatly appreciative.
http://sourceforge.net/tracker/?group_i ... tid=916690

I'm assuming you were building on windows, AFAIK the physx module doesn't work on linux. I
think what is badly needed now is a ctypes implementation of the PhysX Demo's MemoryWriteBuffer/MemoryReadBuffer.