Strengthen the effect of "actor.headsup()"? (Solved)

Sorry if I,m being pushy, I know you guys just solved a issue of mine yesterday, but I really want to know if the “actor.headsup()” feature can be strengthen in the effect of allowing you to move onto surfaces that differ greatly in pitch and roll from the last (ex, from a floor to a wall).

The headsup() feature was doing this on surfaces that don’t differ as greatly from each other just fine, so I tried a cheap division trick to create a sort of middle point for pitch and roll to pass to, then from there, pass to the desired pitch and roll after.

Basically separating one steep difference into two less steep differences that the headsup() can cross through, but the character ends up going all over the place, now, what I want out of this is to make my character be able move onto floors, walls, and the ceiling seamlessly.

So I ask, is there a feature out there for panda3d that can do this better? or can a mathematical calculation better then my trick be cooked up for this? anyway, thank you to anyone who is willing to help.

EDIT: well it seems with my tricks I was able to get onto some walls, but then another problem comes up, and that is, the character will not truly stick to the wall, it’s weird, but I think it is a perspective thing, when I try to go right, the character actually goes right from the world’s perspective not the characters.

For this, I see two possible approaches, offhand. (The examples below show movement to the right, for the purpose of demonstration.)

First, you might try either moving the character relative to itself, like this:

myCharacterNodePath.setPos(myCharacterNodePath, speed*dt, 0, 0)

The first parameter there is the NodePath relative to which we want to move our node. In this case, we’re moving the NodePath relative to itself.

Second, we could move it via its forward, right, and up vectors, like this:

quat = myCharacterNodePath.getQuat(render)
forwardVec = quat.getForward()
rightVec = quat.getRight()
upVec = quat.getUp()

myCharacterNodePath.setPos(rightVec*speed*dt, 0, 0)

Moving the character relative to itself is simple, but may be problematic if you maintain a velocity-vector that you apply to your character. In that case, you may find that the "forward-, right-, and up- vector approach might work better.

1 Like

Thanks for the response, I trying something similar to this, except I used setZ(self.actor, movement * dt), anyway I got a “TypeError: NodePath.set_y() argument 1 must be panda3d.core.NodePath, not panda3d.core.LVector3f” error, maybe the syntax I was using does not mix? anyway, here was the syntax I was using.

chfwd = self.actor.getQuat(self.render)
UpVec = chfwd.getUp()
self.actor.setY(UpVec, movement * dt)

You say:

Where “self.actor” is presumably a NodePath.

But then in your code-excerpt, you have:

Where “UpVec” is presumably a vector.

These are not the same.

And in fact, looking again at my code above, I see now that I did make a mistake! Two, in fact! First, I put in the “rightVec” vector as if it was a component, not a whole vector. Second, I simply assigned the NodePath’s position to that vector (with some multiplication), rather than moving it from its old position to a new position in the direction of that vector. Sorry about all that! A more-correct version might be something like this:

myCharacterNodePath.setPos(myCharacterNodePath.getPos() + rightVec*speed*dt)

To start with, I’m setting the position relative to my current position by adding the new vector to said position. Secondly, I’m just passing in a single parameter (the result of all of that adding and multiplying), which Panda then treats as the new position to be assigned.

Sorry, the Z example I gave was a trick I used to move upward instead forward when the character reach certain pitch, while the Y example was the code I was actually using to implement your idea.

Anyway, I tried you new code and got a "TypeError: unsupported operand type(s) for +: ‘float’ and ‘panda3d.core.LVector3f’ error, thinking it was problem on my side, I change the code from setY() to setPos() and it worked.

But the character when all over the place, I,m guessing I chose a wrong vector or setPos was too global for my situation, I will try the other vectors and get back to you.

EDIT: As quick test, to try all the vectors, I attached them each a headsup, and the results was interesting, the forward worked as intended for headsUp, but the getUp() pushed the character towards the floor while the getRight() seemed to have made to character move onto the wall, but was not attached to it as I would have wanted.

EDIT 2: so I tired all the vectors in the setPos(), and once again, interesting results, the getUp() does nothing from what I can tell, the getForward() makes my character move normally the same way “actor.setY(actor, movement * dt)” does, while getRight() moves the character it it’s side, the forward vector looks promising, but only if I can tilt it 90 degrees towards the sky.

Okay, so I tried your code once again with a added trick, instead of getting the quat of the player object, I would obtain it from a pre-rotated node, that is to have a empty node set a 90.0 P at all times with it’s H always set to the character’s, this way, the getForward() would be obtained from the rotated node and I can apply it to the forward movement.

And it was actually working until I had my character move in any direction other than forward, backward caused the character to shift in the opposite 90.0 degree angle, while the left and right directions caused the character to move 90.0 degree angles with the character’s feet towards those directions.

Rather than moving up, down, left, or right with feet fixed in that 90.0 degree angle as I want, much as it does being on the ground, so judging based on the code you gave me “Thaumaturge” I,m going to also need to move in the right and up vectors too, but how? do you have a code like this for setting of the HPR instead of Pos?

Okay, Thaumaturge, I tired your first approach this time with the character relative approach, I had to make a entire mode around it though, but it seems to be working nicely, so thank you for the solution, however, I’ll keep this thread going to see if I can find a answer to the “headsup” issue.


I will say, I tired this…

self.actor.headsUp(self.actor, Point3(0, 2, 0), entry.getSurfaceNormal)

What I did was add upon the Point3 tuple, adding one more, do you think this is the right way? I still had trouble going up steep surfaces but not as much, I,m wondering if it was the “smooth transition” code I obtained somewhere on this board, here is it if you want to see it

aniHpr = self.actor.getHpr()
self.actor.headsUp(self.actor, Point3(0, 1, 0), entry.getSurfaceEntry)
newHpr = self.actor.getHpr()
newHpr.setX(aniHpr.getX())
self.actor.setHpr(aniHpr)
magicNumber = 90.0
if self.actor.setP() > newHpr.getY():
self.actor.setP(self.actor.getP() - magicNumber * globalClock.getDt())
if self.actor.setP() < newHpr.getY():
self.actor.setP(self.actor.getP() + magicNumber * globalClock.getDt())
if self.actor.setR() > newHpr.getZ():
self.actor.setR(self.actor.getP() - magicNumber * globalClock.getDt())
if self.actor.setP() < newHpr.getY():
self.actor.setP(self.actor.getR() + magicNumber * globalClock.getDt())

Hmm… I’m not sure of whether the problem lies with your “smooth transition” code. You could perhaps find out by temporarily commenting out that section, and seeing whether the character behaves as expected, but without the smoothing.

If the “smooth transition” is the problem, then a potential solution might be to keep another node, a “referenceNode” of sorts, as a sibling of the actor. (That is, it would have the same parent as the actor, so that they’re affected by the same things, but don’t directly affect each other.) This “referenceNode” would use your “headsUp” code, but not your “smooth transition” code–it would simply snap to the appropriate orientation. Your actor would then just smoothly transition to match the orientation of the “referenceNode”.

However, bear in mind that I’m pretty tired as I write this, so the above may not be well-considered; I do stand for correction.

hmm, okay, I,ll try turning it off and trying it, but I do recall really early on, slightly before I implemented sliding into the prototype that it had trouble with the headsup when I first learned of it, but my memory may be hazy.

I suspect that if it’s having trouble without the “smooth transition” code, then it’s unlikely to work better with it. Indeed, the transition may even mask the problem.

I’d suggest getting this working without the transition–just having the character immediately snap to the intended position and orientation–and then polishing it later.

Okay I tired it, and yes you are correct, it seems the “transition code” is the culprit here, but I do not want get rid of it as it looks nice, so I,m going to attempt some modifications on it instead.


I will say on a unrelated note, I retried your second method of setting the position by vector quats, and with the help of the chart in this thread.

I was able to get a grasp of “panda’s vector language” and correctly implement your second method, creating a set position that the character can move around the wall on. here is the code if you want.

quat = actor.getQuat(self.render)
srVec = quat.getRight()
rhtVec = Vec3(srVec.getX(), srVec.getY, -0.0174416)
fwdVec = Vec3(0, 0, -1)
Up: self.actor.setPos(self.actor.getPos() + (fwdVec * Movement * dt))
Down: self.actor.setPos(self.actor.getPos() + (fwdVec * -Movement * dt))
Left: self.actor.setPos(self.actor.getPos() + (rhtVec * Movement * dt))
Right: self.actor.setPos(self.actor.getPos() + (rhtVec * Movement * dt))

So taking your method I was able to test which position the forward vector should be when on walls for it to always look at the sky, same thing with the right, but I wanted the right vector to always remain 90.0 rotated from the forward vector that was looking at the sky, so I tested to see which parameter was closest related and found it.

Thus I was able to create a fixed vector that would take the X and Y parameters from the character’s quat and the Z be the fixed number I found from testing, thus creating the fixed position from those 2 vectors, sorry I was not able to get it right the first time, and huge thanks to you, your 2nd method helped me out massively.

I’m glad that you seem to have found a method that works for you, and if I have been of service! Good luck with the rest of the project. :slight_smile:

Thanks, it looks like you pretty much solved the issues here, as there is nothing more to say, so I’ll mark this thread as solved. once again a big help from you, so thank you.