Problem with vectors defined in Model.Definitions

Found a bug? Post information about it here so we can fix it!

Moderator: Moderators

Post Reply
Kgm
Posts: 7
Joined: Fri Sep 12, 2014 1:57 am

Problem with vectors defined in Model.Definitions

Post by Kgm » Tue Apr 14, 2015 5:59 am

:?

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>

User avatar
VilleK
Site Admin
Posts: 2078
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Post by VilleK » Tue Apr 14, 2015 9:55 am

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.

User avatar
Kjell
Posts: 1733
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell » Tue Apr 14, 2015 1:33 pm

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

User avatar
VilleK
Site Admin
Posts: 2078
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Post by VilleK » Wed Apr 15, 2015 7:29 am

I agree, it isn't ideal behavior when cloning. So I might change this later.

User avatar
Rado1
Posts: 773
Joined: Wed May 05, 2010 12:16 pm

Post by Rado1 » Wed Apr 15, 2015 7:44 am

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

Code: Select all

a = b;
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.

User avatar
VilleK
Site Admin
Posts: 2078
Joined: Mon Jan 15, 2007 4:50 pm
Location: Stockholm, Sweden
Contact:

Post by VilleK » Wed Apr 15, 2015 8:32 am

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.

User avatar
Kjell
Posts: 1733
Joined: Sat Feb 23, 2008 11:15 pm

Post by Kjell » Wed Apr 15, 2015 9:40 am

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

Post Reply