Initializing VBaseX with a tuple?

I noticed that it is possible to create a VecX object using tuples, e.g. v = Vec2( (1,1) ), but it’s not possible to do the same for VBaseX classes.

I tried to add the tuple initialization functionality into the VBase classes and ran into some problems.

  1. I couldn’t find a constructor in any of the lvector*_src.h’s that explicitly initialized the class using a tuple; Is interrogate magically unpacking tuples behind the scene and then calling c++ constructors such as
  INLINE_LINMATH FLOATNAME(LVecBase3)(FLOATTYPE x, FLOATTYPE y, FLOATTYPE z);
  1. Undeterred, I add an explicit pyobject constructor for VBase2,3,4
INLINE_LINMATH FLOATNAME(LVecBase*)(PyObject *objTuple);

When doing this, I had to explicitly expand

INLINE_LINMATH FLOATNAME(LVector3)(FLOATTYPE fill_value);

into

  INLINE_LINMATH FLOATNAME(LVecBase3)(bool fill_value);
  INLINE_LINMATH FLOATNAME(LVecBase3)(float fill_value);
  INLINE_LINMATH FLOATNAME(LVecBase3)(double fill_value);

to dodge some function overloading mismatches.

These adjustments seems to work for VBase3 and VBase4, and I can init them with tuples, VBase3( (1,1,1) ). But for unknown reasons, these changes refuse to work with VBase2. Calling VBase2( (1,1) ) seems to completely skip the new pyobject* constructor code and the object is always initialized to x,y =1. Any ideas on why this is happening?

Zhao

The tuple initializer is actually an unintended consequence of interrogate’s magic typecasting feature.

What’s happening is that when you call Vec3((1,1,1)), it sees that (1,1,1) is not one of the valid parameters to the Vec3 constructor, so it tries to typecast it into something that is a valid parameter. It finds VBase3, which can be initialized with three floating-point numbers, so it calls that a valid typecast and performs it, passing the result to the Vec3 constructor. So Vec3((1,1,1)) is really calling Vec3(VBase3(1,1,1)). It’s the same thing that allows you to call NodePath.setPos((1,1,1)) and other things that normally accept a VBase3 directly.

But it doesn’t work for VBase3, because we don’t perform magic typecasting on an object’s copy constructor (which could lead to infinite recursion).

I don’t know why your attempt to add this feature explicitly failed for VBase2.

But really, if you want to pass a tuple to these constructors, why not just prefix it with a , using the Python convention of expanding tuples into arguments? Like Vec3((1,1,1)) and VBase3(*(1,1,1)).

David

I didn’t know about the pythong *(…) unpacking before. Now I do :stuck_out_tongue:

same here. thanks all for your help.
Cheers.