В Oimo.js телепортация телесных объектов представляет собой изменение их позиции в пространстве без прохождения промежуточных состояний через симуляцию физики. Простое присвоение новой позиции не учитывает текущие линейные и угловые скорости, что может приводить к неожиданному поведению при взаимодействии с другими объектами.
Каждое тело в Oimo.js хранит два ключевых вектора движения:
linearVelocity) —
вектор скорости перемещения тела в пространстве.angularVelocity) —
вектор вращения, задающий скорость изменения ориентации тела.При телепортации тела эти векторы продолжают влиять на его поведение. Например, если объект имел скорость и его позиция мгновенно изменена, при следующем шаге симуляции тело продолжит двигаться с прежней скоростью, что может привести к “выстрелу” тела через другие объекты или некорректным столкновениям.
Для корректной телепортации важно обнулить скорости тела сразу после изменения позиции. В Oimo.js это делается напрямую через свойства объекта тела:
body.position.set(x, y, z); // Новая позиция
body.linearVelocity.set(0, 0, 0); // Сброс линейной скорости
body.angularVelocity.set(0, 0, 0); // Сброс угловой скорости
position.set(x, y, z) — мгновенное
перемещение тела в указанные координаты.linearVelocity.set(0, 0, 0) —
предотвращает сохранение предыдущей инерции.angularVelocity.set(0, 0, 0) —
останавливает вращение тела, обеспечивая стабильность после
телепортации.Сброс скоростей при телепортации предотвращает непредсказуемые реакции физического движка:
Важно учитывать, что мгновенное перемещение тел может вызвать пересечение с другими объектами. Oimo.js не решает коллизии для тел, которые уже находятся в перекрытии после телепортации. Поэтому иногда рекомендуется:
function teleportBody(body, newPosition) {
// Сброс скоростей перед перемещением
body.linearVelocity.set(0, 0, 0);
body.angularVelocity.set(0, 0, 0);
// Перемещение тела
body.position.copy(newPosition);
// Обновление матриц и буферов физики
body.awake(); // активирует тело, если оно было в состоянии покоя
}
awake() гарантирует, что тело
будет участвовать в следующем шаге симуляции, даже если оно находилось в
спящем состоянии.copy() вместо прямого присваивания
позволяет избежать ошибок с ссылками на векторы.linearVelocity и
angularVelocity не обязателен, но может быть полезен при
переводе объекта в динамическое состояние.awake() для активации тела после
перемещения.Эти шаги обеспечивают предсказуемое поведение объектов в Oimo.js при телепортации и позволяют реализовать точное управление позиционированием без нарушения физической симуляции.