Serious vector problem.

is Vec3() (no arguments) supposed to return a zero vector? Because it doesn’t.

from pandac import PandaModules as P
print P.Vec3()
print P.Vec3(40,41,42)
print P.Vec3()

output:

Vec3(0, 0, 0)
Vec3(40, 41, 42)
Vec3(0, 41, 42)

The API refrence doesn’t cover constructor calls. Is this a bug? Or just a bad call with undefined behavior? (If we’re never supposed to create a vector with no arguments I would hope that it would throw an exception or something rather than carry on with undefined state.)

The result is indeed undefined. To be more precise, I think the returned python object is taken from the pool of free references, and that would explain why :

from pandac import PandaModules as P
P.Vec3()
P.Vec3(40,41,42)
a = P.Vec3()
b = P.Vec3()
print a
print b

results to :

Vec3(0, 41, 42)
Vec3(0, 0, 0)

Pros : Creating / deleting objects is faster (especially they are created / deleted in a loop)
Cons : You can waste some time wondering what’s wrong with your Vec3 if you’re not aware of that

Good explanation raytaller.

I still don’t understand why you would even want a blank Vec3.

@raytaller: I don’t think I understand. If Vec3() just pulls the last vector created, why does it reset the x value to 0?
@mavasher: I don’t want a ‘blank’ (whatever that means) Vec3, I want a zero vector. I assumed (perhaps incorrectly) that the default overload constructor created a zero vector, because (as you can see from the output) the first time it actually does return a zero vector. (Also, if you call it multiple times in a row, it apparently returns a zero vector half the time)

hem. Vec3.zero ?

Vec3.zero() is indeed the correct way to get a zero vector.

Of course you wouldn’t, and it is very strange to a Python programmer that this happens. I should probably just unpublish the default constructor to Vec3, so that it is not visible to a Python user.

In the C++ world, it is very common to have objects that do not initialize their memory when you use the default constructor. This is a tiny optimization that allows you to reassign the vector to something meaningful later, without wasting time initializing it to some value (like zero) that you don’t intend to keep. In C++, this is the default behavior for all simple variables. In Python, there is no such concept as an uninitialized variable–variables are not created until they are assigned a value–so it seems very strange to encounter this behavior in Python.

Since Vec3 is really a C++ object, it behaves according to its C++ rules.

That’s not what it does. It pulls random values out of memory. Sometimes a part of it might be from the last vector. Sometimes it will be zero. Sometimes it will be a not-a-number value. The same code may produce two different values on different days, or it may not. There’s really no way to predict what it will be. This is what happens with uninitalized memory. As a Python programmer, you are fortunately (usually) insulated from this sort of oddity of computers.

David

Thanks drwr I think I get it now.

Hmm, so what about the single-argument overload? Is Vec3(0) the same as Vec3.zero() and Vec3(0,0,0)?

The single argument overload seems to set the x y and z to the given value. This would be useful for uniform scaling.

Thanks (But don’t stop at Vec3. If there are any other default constructors that behave that way, they should probably be unpublished too.)

Right, that’s what it does. So Vec3(0) also returns a zero-valued vector.

David

Oops, I thought that Vec3 were reference counted, like None, and that created and deleted instances were kept in a kind of pool