Transparency and Pusher(CollisionHandlerPusher) Questions (Answered/Solved)


#1

Hey, I have a couple of questions, first with panda3d’s transparency, in my game I want to have water, and in some older games I observe that they are just a simple plane that was transparent, I want to attain the same effect, so I has looked around only to find a couple a of solutions, but none worked.

I,m assuming that the solutions worked for the entire model rather then a object that is a part of the model which I,m trying to do, I guess my question for transparency is, it is possible to make a object within a model semi-transparent like a ghost? and if so what are some code examples.


Now on to the pusher question, I have been wrestling with panda3d to attain sliding like Super Mario 64 for a while now but have had no success yet, I have had some theories and ideas. Now because the pusher was made to cancel out collision not throw you.

I have tried to implement a “actor.setY()” function to give the missing force to the collision, but here is my question, is it possible to obtain what direction the pusher is pushing back to (preferably X and Y) like a sort of “pusher.get()” function? so I can set this idea correctly set up, or is there functions to set the pusher’s attributes like it’s X and Y push force to add strength to the push?

I guess here a second additional question related to pusher topic, during my experience with panda when setting a actor’s “H” parameter, it’s directionals also get rotated as well, like a sort of it’s own perspective, so the question is, is there a way to get it’s “unrotated” directionals or do I have to recalculate it’s original position using python?

Thanks to anyone who is willing to help, and have a good day everybody.


#2

If you want to make only part of a model transparent, the easiest way would probably be to reduce the alpha value for the texture on that part using an image editing program.


#3

Regarding transparency, a caveat to what Air_Control said: beware of object-sorting issues. If the water is the only transparent object in the scene, then you may well be fine. However, you may find that if there are other transparent objects you could perhaps encounter problems.

Regarding the “Pusher” question, about physical responses from the Pusher, there are two parts to my answer to that:

First, if I have it correctly, despite its name the “Pusher” doesn’t exert a physical force on an object–it just attempts to place it such that it’s no longer intersecting with the collider in question. If you want a physical reaction when using a “CollisionHandlerPusher”, then a little extra work may be called for. Which brings me to my next point:

Second, remember that “CollisionHandlerPusher” is a sub-class of “CollisionHandlerEvent”, and is just as capable of producing collision-events as is that class. Furthermore, the collision-events generated by Panda include the normal-vector associated with the collision, which can be used to calculate a physical response to apply to your object. (If you’re not familiar with Panda’s collision events, then I believe that the manual covers them, as well as providing example code.)

Regarding your question about an object’s rotations, if you want to get an object’s rotation (or position, or scale) relative to another NodePath, you can do so by specifying that NodePath in the relevant “get” call (i.e. “getHpr”, “getPos”, etc.). If you want the object’s rotation relative to the base node (by default the node named “render”), you might use a call something like this:

rotation = myObject.getHpr(render)

#4

I don’t think there is any alpha channel for the texture, unless you mean something else like opacity?


#5

yes, I believe I tried to map my own functions around the pusher using it’s event features, but what you said about it not really pushing back, is interesting, I actually thought it pushed back enough until you were no longer colliding.

So I guess I have got to write my own code to replicate the push force, as for the rotation, I did not know the “get()” function had such a feature to state another node within it’s parentheses, I was always assume you need to leave it blank, this changes things for me, thanks.


#6

Something like this:

# Find an object in the model named "water" and make it transparent
water = model.find("**/water")
water.setAlphaScale(0.5)
water.setTransparency(TransparencyAttrib.M_alpha)

Yes, that’s what the pusher does. It sounded from your post like what you want is a more complex response, like a bounce, which can be implemented by a physics engine.

I don’t know what you mean by “directionals”, but Panda allows you to obtain any NodePath transform-related value in any given particular coordinate system.

For what it’s worth, if you have two separate questions, it’s better to make two separate topics.


#7

Yeah, for some reason the code example you gave me isn’t working, I do not know if it has to do with everything (except the actor) in the scene sharing a single texture file, if you want I can try provide the game, but it is already above a 5MBs.

As for your pusher response, that’s good, but still I wonder if there is a way grab the direction it is pushing back towards, does the pusher have any “get()” functions? perhaps, like “pusher.getY()” or “pusher.getX()” for example.

For your final response, I meant it’s perspective, because when you tilt the character lets say rightward, rightward becomes it’s north, and so forth, but I believe that “Thaumaturge” has already responded with a solution to this issue.


#8

Generally speaking, in an image file the “alpha channel” is where opacity/transparency is stored, I believe–at least for common file formats. (Alongside the “red”, “green”, and “blue” channels.)

If the image lacks transparency, it might be added in an image-editor.

Which part isn’t working, specifically? Is the code failing to find the NodePath, or is it finding it, applying the next two lines, but not resulting in any transparency? (Or something else?)

I fear that there’s the potential for confusion here, if I understand the “CollisionHandlerPusher” correctly. @rdb, please correct me if I’m mistaken at any point in this!

From jnpickee’s description, I get the feeling that they’re using the term “push” to imply the exertion of a physical force. From my understanding, this is not what the “Pusher” does. Instead, it “pushes” in the sense that it offsets the position of the colliding object far enough that the object is no longer colliding. That is, there is no physical force involved, just a change to the position of the object in question.

As I said above, you can get that via a collision event–a physical response should be related to the “collision normal”, if I’m not much mistaken.

I don’t think that any such methods exist–after all, collisions can happen between multiple objects, and each may have a different collision normal (and thus physical response). Imagine two balls bouncing, one hitting a wall, the other hitting a floor. One should bounce away from the wall, and the other should bounce up. Both balls might be governed by a single “CollisionHandlerPusher”, and thus it would have no single response to report from a “get” function.

Conversely, in Panda’s collision system each impact might generate a separate collision-event, reporting its own collision-normal.


#9

So the surface normal then right? I,m just trying to get a idea what to do next, I tried using surface normals which seem to work in one angle, but later had to character slip up off the slope into and the air, so that is why I was asking about the direction earlier. I still need to try your idea, as it might fix the problem.

Edit: about your response for transparency, I put inputted the code example almost exactly the way rdb gave it to me just after the loader function but no transparency, the water still comes out solid.


#10

Regarding transparency, were there any errors printed out to the console? And does your model contain an object named “water” (with the same lack of capitalisation)? (You can find the answer to the latter question, I think, by calling “model.ls()”, and looking at the output in the console.)

Regarding the surface normal, first check that you’re getting it relative to “render”–as with “NodePath.getHpr”, you can pass a NodePath into “CollisionEntry.getSurfaceNormal” to get the normal relative to that NodePath. So, to get it relative to “render”, you might have something like this:

myEntry.getSurfaceNormal(render)

Other than that, it calls for a bit of maths, I believe. If called for, you may find that it helps to draw what I’m describing!

To start with, you have two things: the velocity of the character (or whatever object is colliding with something), and the surface normal of the collision.

Now, when an object bounces, its velocity ends up mirrored around the surface–it’s a sort of reflection, in a sense. It hits the surface, and bounces back from it.

Now, a handy way of looking at this, I find, is to consider that the velocity is reversed in the direction perpendicular to the surface–that is, moving into- or out of- the surface, but stays (more or less) the same in the direction tangential to the surface–that is, moving along the surface.

For a perfectly elastic collision, the component of the velocity directed “into” the surface might be simply reversed, resulting in an overall velocity just the same as it was, but now moving away from the surface instead of into it. For a very “soft” collision, you might have the velocity become zero in the direction “into” the surface, leaving only the component along the surface–resulting in the character sliding along the surface. And between the two there are degrees of response, with more or less of the velocity’s component “into” the surface being retained after the “bounce”.

So, how do we do this? My own way is like so:

Note that the surface normal points directly out of the surface, and has length 1. That means that by projecting the velocity onto the surface normal, we get the component of the velocity that points “into” the surface.

If we subtract this projection from the velocity, we would remove the component of the velocity that points “into” the surface, resulting in a “soft” collision.

However, if we first multiply the projection by two, and then subtract it from the velocity, we do more than just remove the component–we actually end up with it being reversed. Thus we end up with an “elastic” collision.

Now, let’s say that we want a collision somewhere between the two. As we’ve just seen, it comes down to the value by which we multiply the projection. If we multiply it by 1, we get a “soft” collision; if we multiply it by 2, we get an “elastic” collision. A value between those values provides a collision somewhere between “soft” and “elastic”. In short, for a given collision “elasticity”, we want to multiply the projection by (1 + elasticity).

Does that help?


#11

You know, that sounds like it might work (your surface idea), from what I can get, I think you are describing a sort weak bounce effect then reflects the movement enough so it can be off the surface to fall again on a lower part and of it and repeat sort of like a reverse stairs fashion.

But I,m wondering if it would work in a situation where you wanted run down the slope, it seems more suited for trying to run up it.

About the transparency, no, panda3d would have crashed before telling me anything, and I have looked at the egg file with textedit to know that the names in blender are correct, maybe because I tried to add a glass effect to the water material in bender, it is causing some issues?


#12

Calculating the bounce from the surface normal might work for simple cases, but there will be edge cases where that won’t work properly. I would suggest that if you want complex bounce behaviours, you should be using a physics engine, rather than the built-in collision engine. The built-in collision engine will prevent things from colliding and handle sliding along angled surfaces and walls, but not much more complex physics behaviours than that.

Maybe you could share your model and the exact code you are using to try and give it transparency so we can see why that isn’t working.


#13

Ah, no, for a case like that I probably wouldn’t use physics at all. Much depends on the exact movement “feel” that you want, of course–I haven’t played the game that you mentioned, so I don’t have that to draw reference from–but for simple “running on a platform” movement, I would suggest just detecting the height of the surface and placing the character accordingly. You could have a bit of custom code to animate a bit of a bounce on landing on a platform, or sliding to a halt, for example.

What I suggested would be more appropriate to the case of hitting a wall and bouncing back from it, or tossing a ball and having it bounce around the scene.

(Perhaps a video showing the sort of movement that you have in mind might help here?)

Perhaps, but I’ve had it work rather well in a few projects, as I recall.

Of course, if you want really robust physics, then a physics engine is likely the better bet, indeed. But for simple “bouncing around” physics in a reasonably sparse environment, I think that it could work well enough.

Agreed–it would help to see your code and model, I think. Or perhaps better yet, a small test-case with a simple model and just the code to load it and set up transparency.


#14

Here are your video examples:

Example 1: between (1:54 - 1:58) shows mario being pushed in the direction of the slope where it is possible to descend downward by the gravity, this what I,m trying to achieve, this example is good.

Because it shows mario facing the direction of the push force (forward at first) and sliding downward reaching another slope and that slope pushes accordingly (backward) to keep this progress of sliding down, when I tried this, when my character reached the second slope, the character flew off instead of being pushed in the opposite direction in order to continue the sliding as proper.

Example 2: (5:32 - 5:36) shows the player can fight the slope before the slope overwhelms the character and pushing the character backward, this was sort of explained in a speed running guide that I found by accident before I started this panda3d project here:
https://www.youtube.com/watch?v=LhXONwmKZDI

Where it said that the sliding has it’s own speed that is kept up with the regular speed, and only after the regular speed is interrupted, the sliding speed kicks in and sliding happens. I tried to apply this concept into my code ( I know it’s frowned upon to take the inner working of another game, did so the expedite the learning process and push the project forward).

But it is where the wonkiness begins, as for your request for the prototype, I will upload it but I just removed the sliding functions from it into a separate file to move forward for now, let me reinstall them into the code again and I will try to upload the prototype in while.


#15

I will upload the prototype when I input the sliding functions back into it, just give me a while to do so.


#16

hey, it seems the prototype is too big to upload, it is 5MB while the limit is 3MB, let try to eliminate the sound features then I’ll get back to you.

Edit: okay here is a version with the sound removed, you may experience problems with missing sounds, but I only tested the slopes and they seem to work and demonstrate the problem I,m describing
sliptestns.zip (1.2 MB)

Thaumaturge, just keep moving on the slopes and you will see the character getting stuck and eventually will fly off the ledge, rdb, have a look, let me know if you see any issues.


#17

For that sort of movement, I probably wouldn’t use a “real” physical response, indeed. Instead, I might do something like the following, I imagine: (Note that this is untested, and plucked straight from my mind–it may call for testing, tweaking, or changing–or may not work at all!)

  • As I described for normal platforming, the character’s vertical position would be set by detecting the height of the surface below and simply setting the character’s position accordingly.

  • Sliding would be a “mode”–the character is either “walking” or “sliding”, with separate logic for each. When the character encounters a “slippery slope”, they’re put into “sliding mode”.

  • When sliding, a “downslope” vector is calculated. This would come from the surface normal: I think that it would be a vector with z-component having a sign opposite to the sign of the z-component of the surface-normal, and equal in length to the x-y component (as a whole), and an x-y component with direction the same as the x-y component of the surface-normal, but length equal to that of the z-component of the surface-normal.
    –(In short, it’s a 3D version of the old 2D trick of finding a perpendicular vector by swapping the components of the original vector and negating one of them.)

  • The “downslope” vector is then used to accelerate the character: it would be multiplied by the length of its z-component (so that the character slides more slowly on shallow slopes), and by an acceleration vector (so that you can control the speed of the gameplay), and by the delta-time, as per usual. This would then be added to the character’s velocity.

There are some nuances that I imagine will come up, I daresay, and there are likely other approaches that might be taken. Still, I think that it’s a start to one approach that might work!


#18

That is what I was thinking too, I have already set up a sliding state in the example given, so some work has been done on this, the main problem I kept on running into was the direction of the character. A missing factor was the using the Z movement, yes, but even with that in the equation, I would still run into the directional problem (where to push in the X and Y).

It seem that nintendo had solved this by having Mario always directly face or face away from the slope, which I attempted with the “lookAt” function, sadly the character would only look at the slope maybe a 3rd of the time? causing major wonkiness because the acceleration compared speed of the infrequent "lookAt"s.

Today though, it seems I had made some progress, by getting the surface normals of the character’s collision sphere instead of the render’s and applied a 90 degree add or subtract from the character’s position to make it turn accordingly.

Your post seems interesting, but right now I,m tired, and sadly was only able to skim through your post, I’ll come back to it when I wake up, study it, and try to see if I can obtain some methods from it, thank you vary much for your help.


#19

Well, this is embarrassing to say, but what you said was a little bit beyond my knowledge right now, but I still tried to understand what you said by looking at images, other posts, and youtube videos, and from what I can get are you suggesting mirroring the the surface normal purely based on the Z?

Still, I tried to a apply some of your idea, notably the sliding mode and using the Z to calculate velocity, and I made progress, but, then the old directional problem I have reared it’s head, I’ll try to re-look at your post again, and see if I can understand more later.

Edit: is it possible to get “HPR” for a surface normal, if only I can get that information somehow, the sliding works great if the surface is directly facing or facing away from the character, but I need also the sides too.


#20

I’m sorry to read that you’re still having trouble! :/

And bear in mind that I may be mistaken–as I said, I haven’t tested my suggestion! In fact, thinking about it further, I may have been mistaken: while I suspect that my thoughts were correct for a more physical approach, if you are indeed simply assigning the character’s z-position then it might be incorrect.

(If you’re applying velocity on the z-axis, too, then it might become more complicated again.)

You see, when you just assign the character’s z-position, you’re essentially applying a sort of implicit velocity: the character moves up and down according the to surface, which suggests the presence of a vertical velocity, even if the character only really has an x-y velocity.

In this case, my new thought is to just use horizontal velocity, and have slopes “push” the character horizontally. The steeper the slope, the harder it would “push”. Since the surface-normals of shallow slopes have small x-y components and steep slopes have large x-y components, it makes sense to just use the x-y component of the slope for this “push” (multiplied by an acceleration factor, and by delta-time, once again).

You would also likely want to place a cap of the length of the character’s velocity, so that it doesn’t end up going too fast!

But again, all of this is speculative, so try it and see whether it works!

(And my apologies for inaccurate advice given by me here! ^^; )

Sort of. I was suggesting turning the vector through ninety degrees. But see my new thoughts above!