Motionpath speed

I am using the MopathInterval in order to move my camera in a specific path. I want to modify the speed of the camera during the motion path with the duration parameter. If I set the duration high the camera moves faster and the opposite. I want to do this dynamically.

What I mean is to change the speed of the camera according to a e.g slider while tha motionpath runs.

the following code works fine but instead of just changing the speed of the camera it also moves the camera to the position that was supposed to be according to the new duration.

myMotionPathInterval.duration=sliderDuration['value']

is there any other way to change only the speed of the camera and not the position?

any help here guys ?

is it possible to change the speed of the motion path?

have you already checked out this forum thread?

Thank you for the information.
No, we haven´t seen the specific link before but again doesn´t help.

Its very strange the specific behavior.
Does anyone else had the specific behavior with the duration or I am doing something wrong?
Is there any other parameter except the duration to increase/decrease the speed?

I tried the code below from the specific thread to modify the speed and although the movement of the camera is not smooth it somehow increase or decrease the speed according to the play rate.

self.move = Parallel( self.movePenguin, self.moveCamera )
self.move.start(startT=0, endT=5000, playRate=5)

but I cannot modify the playRate while the motion path moves.

I tried

self.move.playRate=3

while the motion path moves but this doesn´t do anything.
It somehow ignores the specific statement.

any help would be much appreciated

I can’t actually code and test it but my suggestion could work, starting the motion, interrupting it and restart with a different speed at the point it was stopped.
You’ll use pause() to break the motion, getT() to read the time value at the braking point and you’ll use that value issuing again start, as much as:

self.move.pause()
breakingT=self.move.getT()
self.move.start(startT=breakingT, endT=5000, playRate=new_rate) 

here the manual reference of the interval class

lemme know if worked and if you post your piece of working code that will be appreciated.

You can also use an IndirectInterval to control the playback of a seconary interval (such as your MopathInterval). The IndirectInterval plays your secondary interval at whatever speed you like. You’ll have to create a new IndirectInterval each time you want to change the speed.

David

thank you astelix. it works fine.
drwr thanks for the reply although I haven’t tried your suggestion.

the code:

at the init

motionPath = Mopath.Mopath()
motionPath.loadFile("curve.egg")

camera_dummy_node = render.attachNewNode("camera_dummy_node")
base.camera.reparentTo(camera_dummy_node)
        
myInterval = MopathInterval(motionPath,camera_dummy_node,name='MyInterval')

self.move = MetaInterval( myInterval)
self.move.start(startT=0, endT=motionPath.getMaxT(),playRate=0.001) 

later

 d self.move.pause()
            breakingT=self.move.getT()
            if(breakingT<motionPath.getMaxT()):
                self.move.start(startT=breakingT, endT=motionPath.getMaxT(), playRate=sliderDuration['value'])
            

sliderDuration=DirectSlider(range=(0.001,3), value=0.001, pageSize=1, command=showValueDuration,pos = (0,0,-0.9))
        sliderDuration.reparentTo(aspect2d)

attaboy hcvtec :wink:
just one thing: I guess the code chunks you provided are pretty of no use for other ppl in trouble therefore I made off a complete sample:

'''
summary: how to settle up a motion path with speed rate changeable dinamically
by: hcvtec and fabius astelix @ 2009-05
references: https://discourse.panda3d.org/viewtopic.php?p=38694#38694
instructions: shift the slider to the bottom with the left mouse button to change the smiley ball speed along the path.
'''
# Panda imports
import direct.directbase.DirectStart
from direct.directutil.Mopath import Mopath
from direct.interval.MopathInterval import MopathInterval
from direct.interval.MetaInterval import MetaInterval
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectSlider import DirectSlider
from direct.gui.OnscreenText import OnscreenText
from pandac.PandaModules import *

#=====================================================================
#
class World(DirectObject):
  #======================================================================
  #
  def __init__(self):
    #
    self.setup_scene()
    
    # 
    smiley = loader.loadModel('smiley.egg')
    smiley.reparentTo(base.render)
    smiley.setScale(.4)
    
    #** first off you need to instantiate a Mopath class and use it to load the curve
    self.mopath=Mopath()
    self.mopath.loadFile('my_mopath_curve.egg')

    #** then to setup an interval for the motion path...
    self.mpival=MopathInterval(self.mopath, smiley)
    #**  and another one to control the speed changes
    self.move = MetaInterval(self.mpival)
    
    # text and slider controls setup - see below the changespeed method to see how the motion path speed will be changed acting with the slider
    self.speed_control_text=OnscreenText(
      "", style=1, fg=(1,1,1,1), pos=(0.0, 0.2), scale=.04,
      mayChange=True, parent=base.a2dBottomCenter,
    )
    self.speed_control=DirectSlider(
      range=(0.001,3), value=0.001,
      command=self.changespeed,
      pageSize=1, pos = (0,0,-0.9), scale=.3,
    )
    self.speed_control.reparentTo(aspect2d)
    
    # this task will update the speed and such values
    taskMgr.add(self.show_speed,'show_speed')
  #------------------------------------------------------
  #
  def show_speed(self, task):
    s=self.speed_control['value']
    t1=self.mopath.getMaxT()
    t0=self.move.getT()
    self.speed_control_text.setText("s=(%0.3f)  t0=(%0.3f)  t1=(%0.3f)" % (s, t0, t1))
    
    return task.cont
  #------------------------------------------------------
  #
  def changespeed(self):
    self.move.pause()
    s=self.speed_control['value']
    t1=self.mopath.getMaxT()
    # if t0 reach t1 we reset it (NB: actually can't be 0.0 or will be issued an error)
    t0=self.move.getT() if self.move.getT() < t1 else 0.001
    self.move.start(startT=t0, endT=t1, playRate=s)
  #------------------------------------------------------
  #
  def setup_scene(self):
    # *** Setup lighting
    lightLevel=0.8
    lightPos=(0.0,-10.0,10.0)
    lightHpr=(0.0,-26.0,0.0)
    dlight = DirectionalLight('dlight')
    dlight.setColor(VBase4(lightLevel, lightLevel, lightLevel, 1))
    dlnp = render.attachNewNode(dlight.upcastToPandaNode())
    dlnp.setHpr(lightHpr[0],lightHpr[1],lightHpr[2])
    dlnp.setPos(lightPos[0],lightPos[1],lightPos[2])
    render.setLight(dlnp)
    
    # *** Setup scenery
    alight = AmbientLight('alight')
    alight.setColor(VBase4(0.2, 0.2, 0.2, 1))

    base.setBackgroundColor(0.2, 0.2, 0.7, 1.0)
    
    # axis origin
    axis=loader.loadModel('zup-axis')
    axis.setScale(.2)
    axis.reparentTo(render)
    
    # staring camera position
    base.mouseInterfaceNode.setPos(0.0, 26.0, 2.0)
    base.mouseInterfaceNode.setHpr(-4., 35., 1.0)
#-------------------------------------------------------
game=World()

if __name__ == "__main__":
  run()

you just have to provide a proper egg curve named ‘my_mopath_curve.egg’ and run it as usual