В Oimo.js объекты физического мира представлены экземплярами класса Oimo.Body, которые добавляются в физический мир через Oimo.World. Для корректного удаления тела из симуляции требуется учитывать внутренние структуры движка и ссылки на тело, чтобы избежать утечек памяти и ошибок во время шага симуляции.
1. Метод
world.removeRigidBody(body)
Каждое тело, добавленное в мир, хранится во внутреннем массиве
rigidBodies. Для удаления объекта из мира используется
метод:
world.removeRigidBody(body);
Где body — ссылка на удаляемый объект
Oimo.Body. После вызова этого метода тело перестает
участвовать в расчётах силы, столкновений и интеграции.
Важно: удаление должно происходить до следующего шага симуляции, иначе могут возникнуть ошибки, связанные с доступом к уже удалённому телу во время обновления коллизий.
2. Очистка ссылок на тело
Удаление тела из мира не освобождает автоматически все ссылки на него в коде. Если после удаления остаются ссылки, тело может продолжать занимать память. Для безопасного удаления необходимо:
body = null;
или удалять тело из собственных массивов и структур данных:
let index = objectsArray.indexOf(body);
if (index !== -1) objectsArray.splice(index, 1);
Это особенно важно при работе с динамическими объектами, создаваемыми в цикле.
Для сброса мира или удаления всех объектов удобно использовать цикл:
for (let i = world.rigidBodies.length - 1; i >= 0; i--) {
world.removeRigidBody(world.rigidBodies[i]);
}
Обратный цикл необходим, чтобы корректно удалять элементы из массива, не нарушая индексы.
Тела в Oimo.js могут иметь одну или несколько форм (Oimo.Shape), каждая из которых участвует в расчётах столкновений. При удалении тела:
Удаление тела во время расчёта столкновений может вызвать исключения, если движок ещё не завершил обработку текущего шага. Рекомендуется:
toRemove.world.step(timeStep);
bodies.forEach(body => {
if (body.toRemove) {
world.removeRigidBody(body);
}
});
Такой подход предотвращает ошибки в обработке коллизий и интеграции.
rigidBodies напрямую
во время шага симуляции.// Создание тела
let box = world.add({
type: 'box',
size: [1, 1, 1],
pos: [0, 5, 0],
move: true
});
// Отметка для удаления после 3 секунд
setTimeout(() => {
box.toRemove = true;
}, 3000);
// Основной цикл
function update() {
world.step(1/60);
// Удаление помеченных тел
world.rigidBodies.forEach(body => {
if (body.toRemove) {
world.removeRigidBody(body);
}
});
requestAnimationFrame(update);
}
update();
Этот подход обеспечивает безопасное удаление тел без нарушений симуляции и утечек памяти.
Удаление тел — базовая операция, но правильная организация циклов и очистка ссылок критична для стабильности и производительности больших физико-графических проектов.