Problem trying to use PyOde for animation

View: New views
4 Messages — Rating Filter:   Alert me  

Problem trying to use PyOde for animation

by Paulo Teotonio Sobrinho :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi

I would like to use PyOde to drive animations in k3d. I think it can
result in nice physics demos for education with impressive effects like
collision detection. Let me describe what I have in mind.

A simple PyOde simulation has two parts. In the first one pyode class
instances are created and initialized. For example

#First Part
import ode
world = ode.World()
world.setGravity( (0,-9.81,0) )
body = ode.Body(world)
M = ode.Mass()
M.setSphere(2500.0, 0.05)
M.mass = 1.0
body.setMass(M)
body.setPosition( (0,2,0) )
body.addForce( (0,200,0) )
total_time = 0.0
dt = 0.04

In the second part we do the simulation: PyOde classes compute and update
whatever physical properties we want, for example

#Second Part
while total_time<2.0:
     x,y,z = body.getPosition()
     u,v,w = body.getLinearVel()
     world.step(dt)
     total_time+=dt

Now, I'm not sure how to implement that in k3d.

My idea is to use a NullOutputScript node to hold the second part of the
code without the while loop. Then I add Time,x,y and z properties to the
node. Properties x,y,z could be connected to a Position node in order to
locate a k3d sphere object. Time property should be connected to a time
source. In this way, new coordinates are compute whenever Time property
changes and the sphere is animated. Let us called this the SimulationNode.

Now, the first part of the code should be located somewhere else since it
has to be executed once before the simulation starts. The idea here is
that PyOde class instances *world* and *body* should be created only once.
I can put the code in another NullOutputScript node that I call
InitializationNode.

Here is my problem: How to I pass the class instances *body* and *world*
created in the InitializationNode to the SimulationNode?

As far as I know, user properties can only hold fixed types like Boolean,
Scalar,Mesh, etc, therefore I can not use them for passing class objects.
I know class instances *world* and *body* are out there somewhere, so I
think there should be a way to get hold of them inside the SimulationNode
context. Is that possible? Please help.

Note: this problem is not restricted to PyOde and can happen whenever we
have class instances we would like to share between contexts.

Thanks
Paulo

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
K3d-development mailing list
K3d-development@...
https://lists.sourceforge.net/lists/listinfo/k3d-development

Re: Problem trying to use PyOde for animation

by Timothy M. Shead :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Paulo Teotonio Sobrinho wrote:

> I would like to use PyOde to drive animations in k3d. I think it can
> result in nice physics demos for education with impressive effects like
> collision detection. Let me describe what I have in mind.

This sounds fantastic, I'm anxious to see it!

> A simple PyOde simulation has two parts. In the first one pyode class
> instances are created and initialized. For example
>
> #First Part
> import ode
> world = ode.World()
> world.setGravity( (0,-9.81,0) )
> body = ode.Body(world)
> M = ode.Mass()
> M.setSphere(2500.0, 0.05)
> M.mass = 1.0
> body.setMass(M)
> body.setPosition( (0,2,0) )
> body.addForce( (0,200,0) )
> total_time = 0.0
> dt = 0.04
>
> In the second part we do the simulation: PyOde classes compute and update
> whatever physical properties we want, for example
>
> #Second Part
> while total_time<2.0:
>      x,y,z = body.getPosition()
>      u,v,w = body.getLinearVel()
>      world.step(dt)
>      total_time+=dt
>
> Now, I'm not sure how to implement that in k3d.

> My idea is to use a NullOutputScript node to hold the second part of the
> code without the while loop. Then I add Time,x,y and z properties to the
> node. Properties x,y,z could be connected to a Position node in order to
> locate a k3d sphere object. Time property should be connected to a time
> source. In this way, new coordinates are compute whenever Time property
> changes and the sphere is animated. Let us called this the SimulationNode.
>
> Now, the first part of the code should be located somewhere else since it
> has to be executed once before the simulation starts. The idea here is
> that PyOde class instances *world* and *body* should be created only once.
> I can put the code in another NullOutputScript node that I call
> InitializationNode.
>
> Here is my problem: How to I pass the class instances *body* and *world*
> created in the InitializationNode to the SimulationNode?
>
> As far as I know, user properties can only hold fixed types like Boolean,
> Scalar,Mesh, etc, therefore I can not use them for passing class objects.
> I know class instances *world* and *body* are out there somewhere, so I
> think there should be a way to get hold of them inside the SimulationNode
> context. Is that possible? Please help.
>
> Note: this problem is not restricted to PyOde and can happen whenever we
> have class instances we would like to share between contexts.
Excellent summary.  By design, each instance of a scripted node has its
own script engine, which maintains its own state (local dictionary, in
the Python case).  This makes it tricky to share state between nodes,
but is essential to prevent unwanted interaction since, in the pipeline,
multiple scripts may be executing simultaneously.  I'm pretty sure that
Python gives you enough wiggle-room to work around this (anyone?), but
if it doesn't we can add some API to make it practical.  In the
meantime, you might develop a prototype capability using a standalone
script, instead of scripted nodes - i.e. using the Script > Editor and
Script > Play menu items, you could combine both parts of the process
into a single script.  For development purposes, it would be easier to
have everything in one place anyway.

Cheers,
Tim

[tshead.vcf]

begin:vcard
fn:Timothy Shead
n:Shead;Timothy
org:www.k-3d.org
email;internet:tshead@...
title:Founder
x-mozilla-html:FALSE
version:2.1
end:vcard



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
K3d-development mailing list
K3d-development@...
https://lists.sourceforge.net/lists/listinfo/k3d-development

Re: Problem trying to use PyOde for animation

by bART Janssens-2 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Mon, Aug 3, 2009 at 5:30 PM, Paulo Teotonio
Sobrinho<teotonio@...> wrote:
> A simple PyOde simulation has two parts. In the first one pyode class
> instances are created and initialized. For example

That's pretty cool, I had no idea ODE could be used so easily!

> My idea is to use a NullOutputScript node to hold the second part of the
> code without the while loop. Then I add Time,x,y and z properties to the
> node. Properties x,y,z could be connected to a Position node in order to
> locate a k3d sphere object. Time property should be connected to a time
> source. In this way, new coordinates are compute whenever Time property
> changes and the sphere is animated. Let us called this the SimulationNode.

I applied an ugly hack before to do something similar in a single
NullOutputScript. There is an example in
share/scripts/scripted_plugins/ac3d_exporter.py. The idea is to check
for user properties, and if they don't exist add them.

In your case, I would add properties to define mass, radius, force
etc., and put the one-time part of the code inside the if block for
one of the properties. The second part of your code could then be put
after the checks for the properties, where the actual exporter code is
in the example.

One caveat: when you change the script inside the NullOutputScript
node, the context gets reset, meaning that you lose your world object.
To get around that, you should delete the property you use to check if
the one-time part of the code has run (BEFORE editing the script).

Cheers,

--
Bart

------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
K3d-development mailing list
K3d-development@...
https://lists.sourceforge.net/lists/listinfo/k3d-development

Re: Problem trying to use PyOde for animation

by Paulo Teotonio Sobrinho :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message


On Mon, 3 Aug 2009, Timothy M. Shead wrote:
>
>> I would like to use PyOde to drive animations in k3d. I think it can result
>> in nice physics demos for education with impressive effects like collision
>> detection. Let me describe what I have in mind.
>
> This sounds fantastic, I'm anxious to see it!
>

On Tue, 4 Aug 2009, Bart Janssens wrote:
>> A simple PyOde simulation has two parts. In the first one pyode class
>> instances are created and initialized. For example
>
> That's pretty cool, I had no idea ODE could be used so easily!
>

I'm just starting with PyOde, so the example was *really* simple. There
was no collision detection or constraints of any sort so the sphere in the
example just falls forever under the action of gravity.


On Mon, 3 Aug 2009, Timothy M. Shead wrote:

> Excellent summary.  By design, each instance of a scripted node has its own
> script engine, which maintains its own state (local dictionary, in the Python
> case).  This makes it tricky to share state between nodes, but is essential
> to prevent unwanted interaction since, in the pipeline, multiple scripts may
> be executing simultaneously.  I'm pretty sure that Python gives you enough
> wiggle-room to work around this (anyone?), but if it doesn't we can add some
> API to make it practical.  In the meantime, you might develop a prototype
> capability using a standalone script, instead of scripted nodes - i.e. using
> the Script > Editor and Script > Play menu items, you could combine both
> parts of the process into a single script.  For development purposes, it
> would be easier to have everything in one place anyway.

I understand the need to keep local dictionaries isolated on each scripted
node.

The idea of a standalone script works, but I have to take care of the
simulation loop. I'm not sure how to do it in a nice way. Using scripted
nodes and time source takes care of simulation loop for me. Can I do
something similar from within a standalone script? Let us suppose I have a
standalone script like this

class myode():
    def hello(self):
      print 'Hello!'

obj=myode()

def simulation_loop():
   obj.helo()

clock=Document.get_node('Time Source')

I would like the function simulation_loop() be called whenever property
'time' of clock changes. How can I accomplish that nicely? Is there some
sort of callback and event signal mechanism that that can be used here?


On Tue, 4 Aug 2009, Bart Janssens wrote:

>
> I applied an ugly hack before to do something similar in a single
> NullOutputScript. There is an example in
> share/scripts/scripted_plugins/ac3d_exporter.py. The idea is to check
> for user properties, and if they don't exist add them.
>
> One caveat: when you change the script inside the NullOutputScript
> node, the context gets reset, meaning that you lose your world object.
> To get around that, you should delete the property you use to check if
> the one-time part of the code has run (BEFORE editing the script).
>

This (not so ugly) hack works. It means I have something to work with
before a more natural solution can be found.

Thank you both for the suggestions!

Cheers,
        Paulo


------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day
trial. Simplify your report design, integration and deployment - and focus on
what you do best, core application coding. Discover what's new with
Crystal Reports now.  http://p.sf.net/sfu/bobj-july
_______________________________________________
K3d-development mailing list
K3d-development@...
https://lists.sourceforge.net/lists/listinfo/k3d-development