This is the code I use to test it: RegisterScriptOgreVector3(mEngine);
int r;
r = mEngine->RegisterObjectType("AngelscriptTest", 0, asOBJ_REF | asOBJ_NOHANDLE); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "void quit()", asMETHOD(AngelscriptTest, quit), asCALL_THISCALL); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "void test()", asMETHOD(AngelscriptTest, test), asCALL_THISCALL); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "void setcp(vector3)", asMETHOD(AngelscriptTest, setCameraPosition), asCALL_THISCALL); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "void pv(vector3)", asMETHOD(AngelscriptTest, printVector3), asCALL_THISCALL); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "vector3 getcp()", asMETHOD(AngelscriptTest, getCameraPosition), asCALL_THISCALL); assert( r >= 0);
r = mEngine->RegisterObjectMethod("AngelscriptTest", "vector3 bv()", asMETHOD(AngelscriptTest, byValue), asCALL_THISCALL); assert( r >= 0);
// Register the singleton's address that the script will use to access it
r = mEngine->RegisterGlobalProperty("AngelscriptTest app", this); assert( r >= 0);
And it does not work on amd64.
'getcp' returns garbage.
'setcp(vector3(100,100,100))' does not set the camera position to vector3(100,100,100) but to vector3(0,0,0).
What am I missing?
It works when using references.
But that's not solving anything as I can't return/pass by reference in all places.
I don't see any real difference between Ogre::vector3 and the vector3 add-on. You really should be able to use them interchangeably. You should in theory even be able to register the vector3 add-on with AngelScript, and still register the methods that use Ogre::vector3 without any wrapping (though this isn't recommended).
I do see a difference in how you registered the Ogre::vector3 type though. You have registered the opAssign() method, whereas with the vector3 add-on this is not done. Since the type is registered with asOBJ_POD this is not necessary. It really shouldn't be the problem, but it might be the cause of your troubles. I suggest you try not registering this method, and see if it works.
Please let me know if doing that works, and I'll investigate why it causes an error when registering the method.
I don't see the difference between the implementations that is causing the problem either. Perhaps it is the fact that Ogre::Vector3 has everything inlined, maybe the C++ compiler does something differently in this case (though I don't think it should). Are you using GNUC?
I'll see if I can reproduce the problem somehow. Though I don't really have a 64bit Linux platform to debug on. I'll have to rely on the buildbot that Jeremy set up.
I could have sworn I saw the copy constructor on the Ogre::Vector3 class. But as I started writing the test case for reproducing the problem I discovered that for some reason Ogre::Vector3 really doesn't have a copy constructor. This means that the real flag to use when registering the type is asOBJ_APP_CLASS_CA, and not asOBJ_APP_CLASS_CAK that you were using.
This is what is causing your problem on Linux/amd64. On Linux/amd64 with GNUC a class is treated very differently if the copy constructor is declared or not. A class with a copy constructor is always passed through a reference even when the function is declared to pass the type by value. When the copy constructor is not declared, the compiler will pass the type in the CPU registers instead, if the class is small enough. The real complicated part is that when the type is passed in the CPU registers, it is split up by the type of each member, so integer members are passed in the general purpose registers, and float members are passed in the floating point registers. This is why AngelScript doesn't allow these types to be passed by value, the implementation to support that in the native calling convention is just too difficult.
You're not seeing this problem on Windows or Linux 32bit because the existence of the copy constructor or not doesn't make a difference on these platforms.
To get things to work, without changing the Ogre::Vector3 class, it is necessary to use the asOBJ_APP_CLASS_CA flag and then also change all your functions that take the Vector3 type by value in any of the parameters to take the type by reference instead. For example 'setCameraPosition(Vector3 cp)' needs to be changed to 'setCameraPosition(const Vector3 &cp)'.
Awesome!
I'll definitely try that and report back.
I might even file a request for enhancement in the Ogre issue tracker if they'll accept a copy constructor.
That might save people from this issue on 64bit gcc empowered platforms.