OK, I tried it out, and I see what’s happening. When you parent a node under aspect2d, it inherits the scale from aspect2d. That’s a non-uniform scale, so it scales your object differently in X and Z. But here’s the kicker–as your object rotates around under aspect2d, the relative X and Z axes change.
Normally you forget about the non-uniform scale of aspect2d, because the window itself is non-uniformly scaled, and the scale of aspect2d exactly compensates for that scale.
Now. A CompassEffect, by default, counter-rotates the object you apply it to, but doesn’t mess with its scale. So when you counter-rotate an object that has had the non-uniform aspect2d scale applied to it, you rotate the scale with it! Suddenly the aspect2d scale no longer exactly compensates for the scale, and it looks all distorted.
The easy solution is to ask the CompassEffect to fix up the scale too. This is the sort of CompassEffect you will create:
obj.setEffect(CompassEffect.make(aspect2d, CompassEffect.PRot | CompassEffect.PScale))
For reference, here’s the sample program I wrote to test this out:
from direct.directbase.DirectStart import *
from direct.interval.IntervalGlobal import *
from pandac.PandaModules import *
import random
# Make a polygon, and bounce it around the screen.
cm = CardMaker('cm')
cm.setFrame(-0.5, 0.5, -0.5, 0.5)
poly = aspect2d.attachNewNode(cm.generate())
t1 = loader.loadTexture('maps/noise.rgb')
poly.setTexture(t1)
def makeMoveInterval(obj):
px = random.uniform(-1, 1)
pz = random.uniform(-1, 1)
end = Point3(px, 0, pz)
start = obj.getPos()
distance = (end - start).length()
time = distance * 4
roll = obj.getR() + time * 20
i = Sequence(Parallel(obj.posInterval(time, end),
obj.hprInterval(time, VBase3(0, 0, roll))),
Func(makeMoveInterval, obj))
i.start()
makeMoveInterval(poly)
# Choose a center point on the polygon to put smiley.
anchor = poly.attachNewNode('anchor')
anchor.setPos(0, 0, 0.4)
# Attach a smiley square to that anchor point, and put a compass effect to
# keep it upright.
sm = CardMaker('sm')
sm.setFrame(-0.1, 0.1, -0.1, 0.1)
sm.setUvRange(Point2(0.25, 0.0), Point2(0.75, 1.0))
smiley = anchor.attachNewNode(sm.generate())
t2 = loader.loadTexture('maps/smiley.rgb')
smiley.setTexture(t2)
# Note that this CompassEffect appears to cause strange squashing and
# stretching on the smiley square.
#smiley.setEffect(CompassEffect.make(aspect2d))
# This one, however, maintains his aspect ratio correctly.
smiley.setEffect(CompassEffect.make(aspect2d, CompassEffect.PRot | CompassEffect.PScale))
David