Stop rotation on collision [CLOSED]

On 08/01/2015 at 08:16, xxxxxxxx wrote:

Hello Casimir,

to be honest, I had never thought of using Python and Xpresso in this way, but instead had probably used the dynamics system. This is not meant derogatory at all, instead I'm thankful for every new idea.

Anyway, let's get to your problem:

One problem (I'm quite sure you know about this already) could be a wrong configuration of the collision node's mode. By default this is set to bounding box. And this will, depending on your object's shape, probably not work well.

Before coming to the next point, I'm wondering how you test, if this is working?

Probably the main problem is the last rotation value (which is the rotation of the object one frame before the collision happens). Depending on the speed of the rotation, this value may be light years away from the point of collision. Your script (and the entire Xpresso setup) only get's executed once per frame. So you have all the problems, one has to expect when working with discrete values (time is not continuous in this case, but jumps from frame to frame). The correct achieve this, would be to calculate the "collision rotation" and use that in instead of lastRotation.
Check it yourself: Just rotate Object A slowly enough and it will seem to work. The faster Object A rotates the larger the errors will get.

Now, that we talked about that, I'd like to add, that an object node in Xpresso has a "Previous Rotation" output. Personally I regard "open output to store data" a bit hacky. I know, this works and sometimes such a workaround is needed (by the way a similar approach can be done with user data to store arbitrary values in Xpresso (not only the Python node) for later use), but in this case you can get away easier.

And lastly one small note on the Python node:
Inputs don't need to be declared global. This is only necessary for outputs.

The last one after the last one: I don't think, we are talking about a bug in C4D here. And having this said, I'd like to move and rename this thread, if that's ok for you (move to PYTHON Development, rename to "Stop rotation on collision").

On 08/01/2015 at 10:23, xxxxxxxx wrote:

Hi Andreas!

Thanks for your answer!
I shall definately look into it!

And surely you can move and rename the thread, after reading your answer, this indeed seems the wrong place for my thread.

Greetings,
Casimir

On 12/01/2015 at 07:48, xxxxxxxx wrote:

Hi,

Well, the reason why I don't use the dynamics system is because the object I want to rotate simply isn't dynamic. I want to rotate it myself, and never use gravity on that object.

All the rest is clear to me, except how to calculate the "collision rotation".
I've searched on google for a while, but everything I found with collisions has dynamics.
I'm quite sure I know what I need to calculate, just not how to do it.
Are there helper-functions inside C4D that I can use?
Or should I calculate it from nil?

Thanks for looking into this!!

Cheers,
Casimir

On 13/01/2015 at 09:12, xxxxxxxx wrote:

At least I'm not aware of any convenience function to calculate what you need.
In C++ (not in Python) there's the GeColliderEngine, but even that does only help you to calculate, if there's a collision. And what you want, is quite the opposite.
I'll leave this question open to the community for some time. I'm sure there are solutions in literature and surely also on the net for this problem.

On 13/01/2015 at 09:29, xxxxxxxx wrote:

this can be easily solved, but I need to know how do you set the variable "global newRotation"

On 13/01/2015 at 10:06, xxxxxxxx wrote:

Well,

Andreas already pointed me on the fact that I don't need to declare it globally.
I get the value from an object-node (the rotating object) which gives me the current rotation (normally even when it is or should be colliding).

I hope this is what you needed?

Greetings,
Casimir

On 13/01/2015 at 10:14, xxxxxxxx wrote:

what I wanted to know is:how does it rotate?
depending on time? or mouse rotation action? or dynamics? specify whatever thing is rotating it.

On 13/01/2015 at 10:28, xxxxxxxx wrote:

Oh yeah, sorry for that!
I rotate it manually with my mouse, for animation.
In this example it are just two static objects, but in my bigger file even those two objects move depending on other controls.

Cheers,
Casimir

On 13/01/2015 at 10:41, xxxxxxxx wrote:

so when you rotate with the mouse, it stops at a certain rotation "before the collision" and get stuck, correct?

On 13/01/2015 at 11:34, xxxxxxxx wrote:

Yes indeed, and that's kind of what I want, except that now it stops at random rotations.
E.g. sometimes it stops at Pitching 8.45° and sometimes at 9.37°, while it should always be 12°.

On 13/01/2015 at 12:04, xxxxxxxx wrote:

this code is not tested, test it and tell me if it works.

  
    
    
    import c4d  
    #Welcome to the world of Python  
      
    def main() :  
        global isColliding  
      global newRotation  
      global lastRotationOutput  
      global newRotationOutput  
      
      if isColliding == False:  
          lastRotationOutput = newRotation  
          newRotationOutput = newRotation  
      else:  
          newRotationOutput = lastRotationOutput + (2 * (lastRotationOutput - newRotation))
    

On 13/01/2015 at 12:07, xxxxxxxx wrote:

This may make the error smaller. But the principal error stays the same.
I'm sorry I need to stamp on the hopes.
Mohamed, did you read my explanation?

On 13/01/2015 at 12:31, xxxxxxxx wrote:

yea I totally understand where the problem lies, and I tested my code in a simple scene and it failed too "even worse".

I guess a python tag may do it "because you will control the refresh" , but in xpresso it is horrible to do such things

On 14/01/2015 at 06:01, xxxxxxxx wrote:

Yeah I'm looking into that.
But, my problem is, how should I calculate the collision? On that level I have no helper functions to use, so I guess I have to code it whole from nil.