Page 1 of 1
Problem with vectors defined in Model.Definitions
Posted: Tue Apr 14, 2015 5:59 am
by Kgm
Dunno if this is a bug or not, but I noticed clones share the same vectors defined in Model.Definitions. Maybe it was because ZGE copy address of current vector to the clone instead of creating a new one?
Code: Select all
<?xml version="1.0" encoding="iso-8859-1" ?>
<ZApplication Name="App" Caption="ZGameEditor application">
<OnLoaded>
<ZExpression Comment="Misc" Expression="g_Frame = 0;"/>
<ZExpression Comment="Spawn 2 models">
<Expression>
<![CDATA[model m = createModel(Model1);
m.v.X = 10;
m.v.Y = 11;
m.index = 1;
m = createModel(Model1);
m.v.X = 4;
m.v.Y = 5;
m.index = 2;]]>
</Expression>
</ZExpression>
</OnLoaded>
<OnUpdate>
<ZExpression Comment="Misc" Expression="g_Frame++;"/>
</OnUpdate>
<Content>
<Model Name="Model1">
<Definitions>
<Variable Name="v" Type="6"/>
<Variable Name="index" Type="1"/>
</Definitions>
<OnUpdate>
<ZExpression Comment="Print v to the log window">
<Expression>
<![CDATA[if (g_Frame % 60 == 0) {
trace("Model #" + intToStr(CurrentModel.Index) + " [" +
intToStr(CurrentModel.v.X) + "," +
intToStr(CurrentModel.v.Y) + "]");
}]]>
</Expression>
</ZExpression>
</OnUpdate>
</Model>
<Variable Name="g_Frame" Type="1"/>
</Content>
</ZApplication>
Posted: Tue Apr 14, 2015 9:55 am
by VilleK
You are right, this is because vectors are copied by address. I suggest you do "v=vector2(0,0);" in Model.OnSpawn to make it a new vector for every clone.
Posted: Tue Apr 14, 2015 1:33 pm
by Kjell
Hmm,
VilleK wrote:You are right, this is because vectors are copied by address.
But do you considered this to a bug? Having a pointer that points to the same memory space for each clone ( by default ) isn't exactly the desired behavior in my opinion. And when you do want to use the same vector from multiple clones you might as well just use a global vector ( and not waste memory on a pointer per clone ).
K
Posted: Wed Apr 15, 2015 7:29 am
by VilleK
I agree, it isn't ideal behavior when cloning. So I might change this later.
Posted: Wed Apr 15, 2015 7:44 am
by Rado1
From the practical usage POV I agree with Kjell - assignments should copy vectors, not pointers to them. So instead of
Code: Select all
vec4 a, b;
a.X = b.X;
a.Y = b.Y;
a.Z = b.Z;
a.A = b.A;
// or
a = vector4(b.X, b.Y, b.Z, b.A);
it would be more convenient to write just
Ville, is there any special reason why vector variables are treated as pointers? BTW built-in vectors (such as ZApplication.MousePosition) are copied by values; which is little bit inconsistent.
Posted: Wed Apr 15, 2015 8:32 am
by VilleK
Hi Rado1,
I've seen that question in your email too, I haven't had a chance to reply because I've been away to Belgium to meet up with the Image-Line guys.
I agree it is not consistent the way it is.
That arrays are references and typing v1=v2 simply copies the reference is just like in C and C#, which are languages I like and take inspiration from. However that App.CameraPosition=v makes a value copy is confusing, it is because of legacy issues, App.CameraPosition is not internally of the same type as a vec3 in script so it needs to make a value copy. Maybe some day I can clean that up.
And I also agree that some kind of copyArrayElements function would be useful to have built in.
Posted: Wed Apr 15, 2015 9:40 am
by Kjell
Hi Ville,
VilleK wrote:That arrays are references and typing v1=v2 simply copies the reference is just like in C and C#, which are languages I like and take inspiration from. However that App.CameraPosition=v makes a value copy is confusing, it is because of legacy issues, App.CameraPosition is not internally of the same type as a vec3 in script so it needs to make a value copy. Maybe some day I can clean that up.
In C you'd probably take this route .. in which case "v1 = v2" assigns the values ( instead of the address ).
Code: Select all
#include <stdio.h>
typedef struct vec2i vec2i;
struct vec2i
{
int x, y;
};
int main(void)
{
vec2i v1 = {0, 1};
vec2i v2 = {2, 3};
v1 = v2;
v2.x = 10;
char buffer[8];
itoa(v1.x, buffer, 10);
printf(buffer); // Prints "2"
return 0;
}
I guess the primary problem is that the ( dynamic ) vector / matrix types are array-based internally?
K