User defined automatic conversion of math types.

What it says on the tin: a place to discuss proposed new features.
Post Reply
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

User defined automatic conversion of math types.

Post by LtJax »

Hello,

in our project, we're primarily using our own vector/matrix/quaternion types instead of ogre. Whenever we're interfacing with ogre, we have to convert to Ogre's types. If possible, I'd like to have that eliminated and automatically convert from our own types to an ogre-type whenever that's what a function expects. For now, I'd only like to have some-non-ogre-type to ogre-type conversions, though I think that you can also use a similar approach to enable ogre-type to non-ogre-type conversions. As an example, I'll show how to do this with boost and Ogre's Vector3. Brace yourselves, for here's some template meta-programming to make this conversion stuff "safe":

Code: Select all


// This should be added globally
namespace Ogre {
  template <class SourceType, class TargetType> struct ConversionTag : public boost::mpl::false_ {};
}

// Now add this constructor to Ogre::Vector3 - DO NOT make it explicit!
template <class SourceType>
Ogre::Vector3::Vector3( const SourceType& src, const typename boost::enable_if<Ogre::ConversionTag<SourceType, Vector3>, void*>::type hidden=0 )
{
  *this = Convert(src);  
}

Now to use this with your own type, you'd have to "enable" that conversion-constructor by specializing ConversionTag with your type. For example, if I have a vector-type CMyvec3 I'd write:

Code: Select all

namespace Ogre { template <> struct ConversionTag<CMyvec3, Vector3> : public boost::mpl::true_ {}; }
Now I just have to define a "Convert" function to do the actual work, et voilà, I can now stuff my CMyvec3s directly into Ogre functions without calling anything explicitly. Note that the conversion-constructor will only be enabled for types that have ConversionTag set-up correctly, so it's safe and won't interfere with other stuff unintentionally. I'm using the very generic boost templates here just to make my intentions more clear. The functionality could actually be included in Ogre much easier, and without any dependencies:

Code: Select all

// Add this globally
namespace Ogre {
 template <class SourceType, class TargetType> struct ConversionTag {};
}

// Add constructors like this for each math type
template <class SourceType>
Ogre::Vector3::Vector3( const SourceType& other, typename ConversionTag<SourceType,Vector3>::type& hidden=0 )
{
  *this = Convert(other);
}

And as a user I could then "inject" my conversion functions into Ogre like this (Note that you don't actually have to change anything in Ogre for this!):

Code: Select all

namespace Ogre {
  template <> struct ConversionTag<CMyvec3, Vector3> { typedef void* type; }; // Enable the conversion-constructor
  Vector3 Convert(const CMyvec3& rhs) { /* Implement here ... */ }
}
If you guys are interested, I could whip up a patch and submit this. I think it would make working with the API a lot easier and won't break anything existing. Discuss!

Edit: Added code that actually works ;-)
Last edited by LtJax on Sun Jan 09, 2011 9:01 pm, edited 2 times in total.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: User defined automatic conversion of math types.

Post by CABAListic »

If you want to convert your own types to Ogre types, then write a type cast operator for them :) Or a simple function with a very short name.
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

Re: User defined automatic conversion of math types.

Post by LtJax »

CABAListic wrote:If you want to convert your own types to Ogre types, then write a type cast operator for them :) Or a simple function with a very short name.
What if it's not my own types, but some other vectors type I don't want to (or can't) change? With this way, you wouldn't introduce dependencies in either library. It just enables a way to add "glue-code". I already have a very short name, but adding the conversion in a central place and let it be called automatically seems a lot more comfortable.
User avatar
betajaen
OGRE Moderator
OGRE Moderator
Posts: 3447
Joined: Mon Jul 18, 2005 4:15 pm
Location: Wales, UK
x 58
Contact:

Re: User defined automatic conversion of math types.

Post by betajaen »

I was going to submit a papercut similar to this.

In NxOgre, the vector types have a "as", "from" function and a special constructor. Which allows them to be converted into, or converted from another Vector type - not automatically, but without an extra conversion silly functions.

Code: Select all

Vec3 vec(Ogre::Vector3(1,2,3));
Vec3 vec = Vec3::from<Ogre::Vector3>(Ogre::Vector3(1,2,3));

Code: Select all

Ogre::Vector3 vec = Vec3(1,2,3).as<Ogre::Vector3>()
This papercut was going to add these methods to the Ogre Vector3 and Quaternion types.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: User defined automatic conversion of math types.

Post by CABAListic »

What's wrong with an external conversion function:

Code: Select all

Ogre::Vector3 vec = convert_to<Ogre::Vector3>(Vec3(1,2,3))
Or just name it 'to' if you prefer it short. I'm not seeing the need to add anything to Ogre here :)
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

Re: User defined automatic conversion of math types.

Post by LtJax »

It makes the code less readable, where there's really no reason for it to be that way. The problem is that such conversion functions are essentially semantic no-ops. They don't really do anything in terms of control flow (other than copy stuff around, invisibly to the user). They only thing they do, is obscure the more significant code. I agree that if you have statements where you just assign a single variable, like in your example, it doesn't really matter much. But if you have something like:

Code: Select all

Ogre::Matrix3 matrix;
matrix.FromAxes( convert(x), convert(y), convert(z) );
the whole thing becomes a lot more readable if you could just write:

Code: Select all

Ogre::Matrix3 matrix;
matrix.FromAxes(x, y, z);
I don't know about you, but I find the second one infinitely more readable.
Also, having to explicitly convert every time is just annoying to me. I want to write the interesting code pieces, not boilerplate code.
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

Re: User defined automatic conversion of math types.

Post by LtJax »

And of course there is no need. It would just make interoperability a lot easier. Count it as a papercut, if you will.
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: User defined automatic conversion of math types.

Post by CABAListic »

Then why don't you write the type cast operator for your Vectors, like I said? You get implicit conversion with no changes to Ogre required.
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

Re: User defined automatic conversion of math types.

Post by LtJax »

CABAListic wrote:Then why don't you write the type cast operator for your Vectors, like I said? You get implicit conversion with no changes to Ogre required.
Because that would add Ogre as a dependency to my vector library, which I do not want. Also, that would increase coupling, which is always a bad thing!
CABAListic
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 2903
Joined: Thu Jan 18, 2007 2:48 pm
x 58
Contact:

Re: User defined automatic conversion of math types.

Post by CABAListic »

Well, neither do I want to overcomplicate the math classes. Ogre is not a template-heavy library, we do not have Boost as a dependency, so we would have to implement all of those template tricks ourselves. And I don't think this is appropriate.
LtJax
Gnoblar
Posts: 8
Joined: Fri Apr 30, 2010 3:55 pm

Re: User defined automatic conversion of math types.

Post by LtJax »

As I said, you don't need boost for this. It's very easy to implement in Ogre itself. It's 3 lines globally and 4 lines for a new constructor in each math class. That's it! It doesn't add any other dependencies and it would make my life (and I guess that of many others) endlessly easier.
User avatar
LiMuBei
Goblin
Posts: 297
Joined: Mon Jun 09, 2008 3:56 pm
Location: Karlsruhe, Germany
x 10

Re: User defined automatic conversion of math types.

Post by LiMuBei »

I'm with LtJax on this, looks very clean, unintrusive and useful.
Post Reply