Common library with physics engine
-
imguin
- Gnoblar
- Posts: 3
- Joined: Fri Apr 04, 2008 9:36 pm
Common library with physics engine
I use OGRE and Bullet together. Both of these libraries have their own vector class. It would be much more easier and faster if they would use the same class. The same goes for angles.
It would be also good if they would have a common terrain and mesh class. To make a hull mesh in bullet I have to extract information from Ogre mesh and then create a bullet mesh from it. In the end it uses twice as much memory as needed and it is "slow". If they would have a common class, we could create a mesh and then send the pointer of the mesh to bullet.
The same goes for every other physic library. It would be great if these engines would make a common library containing these classes. Is it possible to cooperate with one of them?
It would be also good if they would have a common terrain and mesh class. To make a hull mesh in bullet I have to extract information from Ogre mesh and then create a bullet mesh from it. In the end it uses twice as much memory as needed and it is "slow". If they would have a common class, we could create a mesh and then send the pointer of the mesh to bullet.
The same goes for every other physic library. It would be great if these engines would make a common library containing these classes. Is it possible to cooperate with one of them?
- betajaen
- OGRE Moderator

- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
- Contact:
- haffax
- OGRE Retired Moderator

- Posts: 4823
- Joined: Fri Jun 18, 2004 1:40 pm
- Location: Berlin, Germany
- x 8
- Contact:
- PolyVox
- OGRE Contributor

- Posts: 1316
- Joined: Tue Nov 21, 2006 11:28 am
- Location: Groningen, The Netherlands
- x 18
- Contact:
It's a bad thing to do! Well, there are various issues - firstly the internals of the classes may change though for something as simple as a vector this is probably not likely. Maybe it happens with matrices, quaternions, etc though. Secondly, what if the two libraries are compiled on different compilers, or on the same one but with different optimizations? This could have an effect on how the data is laid out. I'm sure that in reality it works fairly well, but it's still bad practice...betajaen wrote:It's very risky. But in PhysX and Ogre, the NxVec3 and Ogre::Vector3 classes are identical (from a variable point of view) - three floats. I've static_cast'd a NxVec3 into a Ogre::Vector3 function quite a few times and it's been fine.
I'm sure somebody will tell me that's a bad thing though.
As for the original question... well yes the situation sucks. But it's not limited to Ogre and physics - it affects pretty much any large software system which involves integrating many components. In the case of Ogre and physics engines there can me many reasons why maths libraries are duplicated. Ther are licensing issues, slightly differing requirements ,coding standards, and good old NIH Syndrome.
Basically you should look into the Adapter (also known as Wrapper) pattern in the GoF book. Not there are two variants (object and class) which can be useful in difernt situations.
- chmod
- Greenskin
- Posts: 131
- Joined: Tue Feb 25, 2003 10:33 pm
- Location: Seattle, Washington USA
I just haul these inlines around in utils.h
(for physx)
Code: Select all
inline Ogre::Vector3 ogrevec(NxVec3 vec) {
return Ogre::Vector3(vec.x, vec.y, vec.z);
}
inline NxVec3 nxvec(Ogre::Vector3 vec) {
return NxVec3(vec.x, vec.y, vec.z);
}
inline Ogre::Quaternion ogrequat(NxQuat quat) {
return Ogre::Quaternion(quat.w, quat.x, quat.y, quat.z);
}
inline NxQuat nxquat(Ogre::Quaternion quat) {
NxQuat new_quat;
new_quat.setWXYZ(quat.w, quat.x, quat.y, quat.z);
return new_quat;
}-
reptor
- Ogre Magi
- Posts: 1120
- Joined: Wed Nov 15, 2006 7:41 pm
- Location: Finland
- x 5
The idea of having the same 3D mesh for visual and for physical representation of an object is often not good I think.
The problem is that the visual presentation often needs to be much more complex than what the physical representation needs to be. You should not give the physics engine any more complex a mesh than is necessary.
I have seen in commercial games this being done so that there are two or more versions of the same 3D model. One for visual and one for physical representation of the object.
The visual model can then have more versions, so-called LODs, level-of-details, which have reduced complexity compared to the first visual mesh. This is done to make it possible to dynamically select a less-complex mesh for display when game situation allows it. This results in better performance.
I have also seen meshes which are used only by Artificial Intelligence. View determination being an example.
My point here being, it is not possible to combine the visual and the physical 3D mesh but only in the most simple cases.
The problem is that the visual presentation often needs to be much more complex than what the physical representation needs to be. You should not give the physics engine any more complex a mesh than is necessary.
I have seen in commercial games this being done so that there are two or more versions of the same 3D model. One for visual and one for physical representation of the object.
The visual model can then have more versions, so-called LODs, level-of-details, which have reduced complexity compared to the first visual mesh. This is done to make it possible to dynamically select a less-complex mesh for display when game situation allows it. This results in better performance.
I have also seen meshes which are used only by Artificial Intelligence. View determination being an example.
My point here being, it is not possible to combine the visual and the physical 3D mesh but only in the most simple cases.
-
voxel
- Gnome
- Posts: 334
- Joined: Wed Aug 02, 2006 9:27 am
- Location: Toronto, Canada
I fully agree...reptor wrote:I have seen in commercial games this being done so that there are two or more versions of the same 3D model. One for visual and one for physical representation of the object.
I use these conversion routines (unoptimized because I'm still early in my project):
Code: Select all
inline Ogre::Vector3 toVector3(const btTransform& t)
{
Ogre::Vector3 v(t.getOrigin().getX(), t.getOrigin().getY(), t.getOrigin().getZ());
return v;
}
inline Ogre::Vector3 toVector3(const btVector3& t)
{
Ogre::Vector3 v(t.getX(), t.getY(), t.getZ());
return v;
}
inline btVector3 toVector3(const Ogre::Vector3& t)
{
btVector3 v(t.x, t.y, t.z);
return v;
}
inline Ogre::Quaternion toQuaternion(const btQuaternion& q)
{
Ogre::Quaternion v(q.getW(),q.getX(), q.getY(), q.getZ());
return v;
}
inline btQuaternion toQuaternion(const Ogre::Quaternion& q)
{
btQuaternion v(q.x, q.y, q.z, q.w);
return v;
}
inline btTransform toTransform(const Ogre::SceneNode* node)
{
btTransform t;
t.setIdentity();
t.setOrigin(toVector3(node->getWorldPosition()));
t.setRotation(toQuaternion(node->getWorldOrientation()));
return t;
}
Last edited by voxel on Tue Apr 08, 2008 6:44 am, edited 1 time in total.
-
btmorex
- Gremlin
- Posts: 156
- Joined: Thu May 17, 2007 10:56 pm
I do something similar that's probably less efficient, but makes my life easier. I just subclass Ogre::Vector3 and then use my own subclassed version everywhere with automatic conversions to bullet vectors.
This allows me to use my vector3 wherever either an Ogre::Vector3 or a btVector3 is expected/returned.
You can ignore the m_valid stuff. I'll probably end up removing it, but I like the fact that I can test whether the vector was actually initialized with something.
Code: Select all
class vector3 : public Ogre::Vector3
{
public:
vector3() : Ogre::Vector3(), m_valid(false) {}
vector3(const Ogre::Vector3& v) : Ogre::Vector3(v), m_valid(true) {}
vector3(const btVector3& v) : Ogre::Vector3(v.x(), v.y(), v.z()), m_valid(true) {}
vector3(const real& x, const real& y, const real& z) : Ogre::Vector3(x, y, z), m_valid(true) {}
operator bool() const
{
return m_valid;
}
operator btVector3() const
{
return btVector3(x, y, z);
}
private:
bool m_valid;
};
You can ignore the m_valid stuff. I'll probably end up removing it, but I like the fact that I can test whether the vector was actually initialized with something.
- Kojack
- OGRE Moderator

- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 538
I use a template function:
It can convert any class with x,y,z components into any other class with x,y,z components, regardless of memory organisation, datatypes, extra members, etc.
So I can do:
For all game stuff I use my own math classes (wrote part of them about a decade ago) and convert to/from ogre and other libs only when needed.
I was once looking at using Blitz++, it's the only independent math library I've seen which doesn't look painful to use. But it still didn't have all the features I wanted, and adding them would be hard because Blitz++ is a massively templated meta programmed library (think of Boost). Like all massively templated libraries, running in debug is like swimming in tar, but release builds run damn fast.
Although Blitz++ did give me the idea to let me initialise vectors like this:

Code: Select all
template <typename T1, typename T2>
T1 convertVector3(const T2 &v)
{
T1 result;
result.x = v.x;
result.y = v.y;
result.z = v.z;
return result;
}So I can do:
Code: Select all
NxVec3 nv;
Ogre::Vector3 ov = convertVector3<Ogre::Vector3>(nv);I was once looking at using Blitz++, it's the only independent math library I've seen which doesn't look painful to use. But it still didn't have all the features I wanted, and adding them would be hard because Blitz++ is a massively templated meta programmed library (think of Boost). Like all massively templated libraries, running in debug is like swimming in tar, but release builds run damn fast.
Although Blitz++ did give me the idea to let me initialise vectors like this:
Code: Select all
kf::Vector3 v = 0, 1, 0;
-
imguin
- Gnoblar
- Posts: 3
- Joined: Fri Apr 04, 2008 9:36 pm
I understand now the problems with using the same mesh. However I still believe it would be easier to use a common library (although I have every needed functions).
However, I see the problems, so I won't complain anymore.
Thanks for the codes, today I've learned about inline functions.
Kojack: I was curious, so I tried these out:
Neither of them works. Maybe it's Blitz++ specific, or not supported by MingW.
However, I see the problems, so I won't complain anymore.
Thanks for the codes, today I've learned about inline functions.
Kojack: I was curious, so I tried these out:
Code: Select all
btVector3 test=1,1,1;
Vector3 test=1,1,1;
- anomalous_underdog
- Kobold
- Posts: 30
- Joined: Tue Aug 21, 2007 8:20 pm
damn that's weird c++ syntax. are you sure that's no typo? I tried looking at the Blitz++ homepage and I didn't see any mention of thatKojack wrote: I was once looking at using Blitz++, it's the only independent math library I've seen which doesn't look painful to use. But it still didn't have all the features I wanted, and adding them would be hard because Blitz++ is a massively templated meta programmed library (think of Boost). Like all massively templated libraries, running in debug is like swimming in tar, but release builds run damn fast.
Although Blitz++ did give me the idea to let me initialise vectors like this::)Code: Select all
kf::Vector3 v = 0, 1, 0;
-
CABAListic
- OGRE Retired Team Member

- Posts: 2903
- Joined: Thu Jan 18, 2007 2:48 pm
- x 58
- Contact:
- nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Doesn't 0, 1, 0 evaluate to 0? Shouldn't it be {0, 1, 0}? But then, Ogre::Vector3 has a constructor, which means you can't use array-initialization.CABAListic wrote:Well, it's certainly possible to do that (so no typo), though I'd also advise to stay clear of such things. It seems more like a way to show how "clever" you can be with C++ without actually improving your code as such. It's still kind of cool technically
- betajaen
- OGRE Moderator

- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
- Contact:
- nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
Since when can you overload operators for built-in typesbetajaen wrote:You could probably get away with overloading the "operator,(float)" and store them very temporarily in a static container somewhere but it would be very stupid; since it would overload everything with a float regardless if it used with a Vector3 or not.
-
CABAListic
- OGRE Retired Team Member

- Posts: 2903
- Joined: Thu Jan 18, 2007 2:48 pm
- x 58
- Contact:
No, you need to overload the operator= of kf::Vector3 to accept an arbitrary helper type. This helper type must be constructible from float and provide an overload for operator,(float). So what the compiler then does is construct a Helper object which sequentially accepts additional float values via operator, then is assigned to kf::Vector3 which reads the first three stored values from it (similarly, kf::Vector4 would read the first four from it, etc.).
- nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
CABAListic wrote:No, you need to overload the operator= of kf::Vector3 to accept an arbitrary helper type. This helper type must be constructible from float and provide an overload for operator,(float). So what the compiler then does is construct a Helper object which sequentially accepts additional float values via operator, then is assigned to kf::Vector3 which reads the first three stored values from it (similarly, kf::Vector4 would read the first four from it, etc.).
Oh, totally. That seems like a good coding practice! I love it. And I'm not being sarcastic or anything, come on now...
- Kojack
- OGRE Moderator

- Posts: 7157
- Joined: Sun Jan 25, 2004 7:35 am
- Location: Brisbane, Australia
- x 538
Hehe.
I never use the v=0,1,0 syntax in my own code, it's just there to freak out all the c++ coders who don't understand "operator,".
(Which is a surprisingly large number of people)
Here's how I did it, no helper types needed:
So when I do:
v = 1,2,3
the result is to first call operator= and set the vector to 1,1,1 and returns a reference to it. The first operator, takes the vector, shuffles z into y and puts 2 into z (vector is now 1,1,2). The second call to operator, shuffles z into y again, and puts 3 into z (vector is now 1,2,3). The commas actually directly operate on the variable on the left, rather than build an object on the right and assign it.
Boost uses the comma operator in assign, detail, iostreams, lambda, parameter, python, spirit, test and xpressive.
I never use the v=0,1,0 syntax in my own code, it's just there to freak out all the c++ coders who don't understand "operator,".
(Which is a surprisingly large number of people)
Here's how I did it, no helper types needed:
Code: Select all
inline Vector3T &operator=(T c)
{
x = c;
y = c;
z = c;
return *this;
}
inline Vector3T &operator,(T c)
{
y=z;
z=c;
return *this;
}
v = 1,2,3
the result is to first call operator= and set the vector to 1,1,1 and returns a reference to it. The first operator, takes the vector, shuffles z into y and puts 2 into z (vector is now 1,1,2). The second call to operator, shuffles z into y again, and puts 3 into z (vector is now 1,2,3). The commas actually directly operate on the variable on the left, rather than build an object on the right and assign it.
Boost uses the comma operator in assign, detail, iostreams, lambda, parameter, python, spirit, test and xpressive.
- betajaen
- OGRE Moderator

- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
- Contact:
I've tried writing my own Boost style Parameter class once with the general usage being:
I've managed to get "x=10" to compile and actually work, but I have never managed to use the "operator," correctly. With this little insight Kojack posted I'm going to have another stab at it. Actual documentation on the "operator," class is quite rare it seems.
Code: Select all
Vector3 vec3 = Vector3((x = 10, z = 10.0f, y=13.0f, normalise = true));- betajaen
- OGRE Moderator

- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
- Contact:
Was?
Perhaps http://en.wikipedia.org/wiki/Whitespace ... _language) could be literally ported to C/C++ just using a white space operator.
Perhaps http://en.wikipedia.org/wiki/Whitespace ... _language) could be literally ported to C/C++ just using a white space operator.
- betajaen
- OGRE Moderator

- Posts: 3447
- Joined: Mon Jul 18, 2005 4:15 pm
- Location: Wales, UK
- x 58
- Contact:
Well thanks to Kojack and still being relativity inside the topic of this thread. I finally managed to complete my "Boost Parameters" classes and most likely drop the string param system from NxOgre.
Observe:
Which outputs:
Thanks Kojack!
Observe:
Code: Select all
using namespace Params;
// Only need to declare these once.
PARAM(Mass, float);
PARAM(Gravity, bool);
PARAM(x, float);
PARAM(y, float);
PARAM(z, float);
class Foo {
public:
void Bar(Params::Parameters p) {
std::cout << "Number of Params = " << p.Params.size() << std::endl;
for (int i=0;i < p.Params.size();i++)
p.Params[i].debugPrint();
}
};
void main() {
Foo* foo = new Foo();
foo->Bar((Mass = 10.0f, Gravity = false, x = 10.0f, z = 70.0f, y = 32.0f));
delete foo;
}Code: Select all
Number of Params = 5
struct Params::_Identifiers::Mass -> 10
struct Params::_Identifiers::Gravity -> 0
struct Params::_Identifiers::x -> 10
struct Params::_Identifiers::z -> 70
struct Params::_Identifiers::y -> 32Thanks Kojack!
- nullsquared
- Old One
- Posts: 3245
- Joined: Tue Apr 24, 2007 8:23 pm
- Location: NY, NY, USA
- x 11
