Я давно заметил что весь модуль direct написан на скорую руку и с кучей всякого родя сюрпризов. Возможно MotionPath использует формулу для получения времени на каждый сегмент пути поэтому время прохождения меняется. Я думаю для собственных задач лучше писать свои решения, так как весь путь строится из массива векторов, то не сложно реализовать что то вроде этого.
Код
from direct.showbase.ShowBase import ShowBase
from panda3d.core import Vec3
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# Просто визуализация точек.
self.p0 = base.loader.load_model("models/smiley")
self.p0.set_pos(Vec3(0, -10, 0))
self.p0.reparent_to(render)
self.p1 = base.loader.load_model("models/smiley")
self.p1.set_pos(Vec3(10, 0, 0))
self.p1.reparent_to(render)
self.p2 = base.loader.load_model("models/smiley")
self.p2.set_pos(Vec3(0, 50, 0))
self.p2.reparent_to(render)
# Тумблер переключения, нужен для однократной смены точки.
self.lever = False
# Путь описывается точками по которым движется объект в виде векторов.
self.path = [Vec3(0, -10, 0), Vec3(10, 0, 0), Vec3(0, 50, 0)]
# Скорость движения.
self.speed = 15
# Собственно сам объект.
self.obj = base.loader.load_model("models/smiley")
self.obj.set_pos(0, 50, 0)
self.obj.reparent_to(render)
# Установим изначальный вектор направления.
self.current_vector = self.path[0] - self.obj.get_pos()
base.taskMgr.add(self.move, "move")
# Счетчик секвенции.
self.step = 0
def move(self, task):
# Время прошедшее за кадр.
dt = base.clock.dt
# Текущая позиция объекта.
obj_pos = self.obj.get_pos()
# Проверяем на котором растоянии находится объект.
if (obj_pos - self.path[self.step]).length() <= 0.15:
# Управление тумблером.
if self.lever == False:
# Простая секвенция на три позиции.
if self.step <= 1:
self.step += 1
else:
self.step = 0
# Меняем вектор направления.
self.current_vector = self.path[self.step] - obj_pos
# Переключаем тумблер.
self.lever = True
else:
# Сброс тумблера в исходное состояние.
self.lever = False
vec = self.current_vector
vec.normalize()
# Перемещаем объект.
self.obj.set_pos(self.obj, vec*self.speed*dt)
return task.cont
app = MyApp()
app.run()
Здесь используется обратная формула, конечно это вызывает проблемы проскока мимо точек при высокой скорости, однако если поколдовать думаю можно это обойти дополнительными проверками. Сейчас в примере используется нормализация вектора, это дает равномерную скорость. Чтоб получить обратную проблему, нужно закомментировать строку:
и установить скорость.