SetPos is affected by Scale

Why the setPos relative command

node.setPos(node,x,y,z)

must be affected by scale ? it’s a complication for me. I have to
make a parent node like this :

p=NodePath("")
node=load...
node.reparentTo(p)
node.setScale(sx,sy,sz)
p.setPos(p,x,y,z)

so i must distinguish between a node to move and the node to scale.

This is a very big problem, and force me to reparent objects to only non-scaled ones, or i will be full of movement odds in the game.

[/code]

imagine 2 cubes with the distance of 1 panda unit. under a node. now scale the node.
if you dont scale positions, the cubes will stay at their positions but will reduce their size.
thats very unnatural way of handling things. usualy you would the entire node and all its children to scale down without breaking your geometry.

if you want to scale without you might want do to somethin like

scaleFixValue=node.getScale(render)
node.setPos(node,x/scaleFixValue,y/scaleFixValue,z/scaleFixValue )

havent tested it at all but something like that should work

I understand your point, and this is useful for scaling objects changing their position also, to preserve their distance relationships.

However this is how the SCALE affect the POSITION when use the setScale, but what i’m arguing it’s why the use of setPos must necessarily be affected by the scale of the object, this is not clear in the manual.

Anyway mine is only a point of view, and maybe i find useful some other way of thinking. The solution exists and i apply it.

Thanks.

Note that if you use p.setPos(p, x, y, z), you’re basically moving p relative to itself – relative to its own position, rotation and thus also its own scale. Usually you indeed just want relative to its own position or so, like this:

p.setPos(p.getPos() + Vec3(x, y, z))

So, as you put it, the position is affected by the scale just because you told it to – by adding “p” as first argument.

If you still want to add the extra “p” argument to the front you can apply the scale of the model using p.flattenLight(), I think. This applies the scale to the vertices themselves.

You can also create a dummy node and add your scaled node to it. Then just move the dummy node around that has 1 to 1 scale while still having your object be the proper size.

Hi.
@pro-soft
This method getPos+Vec3 is not suitable, i think, because it does not take into account of rotation, but sometimes i apply this method without problems.

@treeform
This is exactly what i do, as said on the first post, and it works gracefully, but recurring to new nodes could lead to performance issues for larger nodetrees.

Thanks.

performance with nodes? Nodes is not performance killers geom nodes are - and you have not created any geom nodes.

Wow. This sounds very good to me. My line of thinking is often to make ghost nodes for almost everything.

So i can apply this method without trouble myself. Thanks.

Does anyone know of a way to fix this with directGUI widgets?
As it is, with both scaled and unscaled buttons, positioning to (-1, 0, 1) doesn’t give the topleft corner.
The left is shifted about 1/8th of the screen to the right, and the top is above the top of the screen (basically, the bottom of the widget is about equal to the top of the screen, a little below)

Inverting that for bottomright is not even the same result inverted though. As the right is still about 1/8th the way away, but the bottom is a good bit above the bottom of the screen.
I got it so I could place the x axis so that -1.3/1.3 = the edges, and for the y (or z it seems O.o ) axis it is about 0.96/1.1 (or close to those)

I tried the getPos + vec idea, and treeform dummy node idea (though not sure if I did it correctly, I made a NodePath("") and reparented to render, then reparented the button to it - I also tried reparenting the button back to render after I moved it), but, in neither case did it work, the former moves the button the exact same, and the latter fails to even render the button anymore…

This is just running the directButton example in the manual and trying to move it.

I figured this was the right place to ask this as this thread seems to be about the same issue - but if not just let me know :wink:

Thanks in advance :slight_smile:

This isn’t really the same thing as this thread at all, but OK.

aspect2d is scaled so that the proportions are even. This means that, because your window isn’t square, the coordinates aren’t equal. (If you made your window square then (-1, 0, 1) would indeed be the top-left corner.) Since a typical window is 4/3 wider than it is tall, it means that the top-left corner in a window this shape is (-1.3333, 0, 1).

But you don’t need to think about this. Just parent your objects to base.a2dTopLeft instead. Under this node, (0, 0, 0) is the top-left corner.

You still need to place your object properly with respect to its own origin, of course.

David

Ok, sorry this wasn;t the right place, I thought it might be a scale issue - but obviously not now that I look at it.
But I need something a little more powerful than that, ie, I can set topleft, but reparentng ther and then trying to position to th etop right from it (so move the widget then by 1 or 2 depending) gives even more odd results…

Is there a generic positioner that just puts the object on the screen at -1/1 topleft, 1/-1 bottomright?
Otherwise that seems rather limiting…
Perhaps there is a way to use ortho view for the gui?

Thanks for the help BTW – would you like me to start a new thread for this instead of continuing here?
Cheers!

You have more than just a2dTopLeft. The full list is:

base.a2dTopLeft
base.a2dTopRight
base.a2dBottomLeft
base.a2dBottomRight
base.a2dTopCenter
base.a2dBottomCenter
base.a2dLeftCenter
base.a2dRightCenter

So if you want it on the top right, parent it to base.a2dTopRight.

There are other ways to do the same thing. You also have the numeric values base.a2dTop, base.a2dBottom, base.a2dLeft, and base.a2dRight, which define the dimensions of the screen (for instance, base.a2dLeft and base.a2dRight are -1.3333 and 1.3333). Furthermore, you could just position things relative to render2d, using Panda’s relative scene graph operations, like this:

obj.setPos(render, -1, 0, 1)

which puts it on the top left.

But using one of the various node parents, above, is better because these automatically adjust themselves if you resize the window.

David

Ok, thanks, the latter is what I was hoping for actually, as I have already disabled resizing the window :wink:

Thank you much :slight_smile: