UNPKG

@polygonjs/polygonjs

Version:

node-based WebGL 3D engine https://polygonjs.com

137 lines (136 loc) 4.59 kB
"use strict"; import { CorePhysics, CorePhysicsLoaded } from "./CorePhysics"; import { Vector3 } from "three"; import { _physicsCreateRBD, physicsUpdateRBD } from "./PhysicsRBD"; import { physicsCreateJoints } from "./PhysicsJoint"; import { PhysicsIdAttribute } from "./PhysicsAttribute"; import { clearPhysicsPlayers, createOrFindPhysicsPlayer } from "./player/PhysicsPlayer"; import { coreObjectClassFactory } from "../geometry/CoreObjectFactory"; export const PHYSICS_GRAVITY_DEFAULT = new Vector3(0, -9.81, 0); const physicsworldByGraphNodeId = /* @__PURE__ */ new Map(); const objectsByRBD = /* @__PURE__ */ new WeakMap(); const rigidBodyById = /* @__PURE__ */ new Map(); export async function createOrFindPhysicsWorld(node, worldObject, gravity) { const nodeId = node.graphNodeId(); const PhysicsLib2 = await CorePhysics(); let world = physicsworldByGraphNodeId.get(nodeId); if (!world) { world = new PhysicsLib2.World(gravity); physicsworldByGraphNodeId.set(nodeId, world); } return { world, PhysicsLib: PhysicsLib2 }; } export function physicsWorldNodeIdFromObject(worldObject) { const nodeId = coreObjectClassFactory(worldObject).attribValue(worldObject, PhysicsIdAttribute.WORLD); return nodeId; } export function physicsWorldFromObject(worldObject) { const nodeId = coreObjectClassFactory(worldObject).attribValue(worldObject, PhysicsIdAttribute.WORLD); if (nodeId == null) { return; } return physicsworldByGraphNodeId.get(nodeId); } export function physicsWorldFromNodeId(nodeId) { return physicsworldByGraphNodeId.get(nodeId); } export function initCorePhysicsWorld(PhysicsLib2, worldObject, scene) { const world = physicsWorldFromObject(worldObject); if (!world) { console.warn("no physicsWorld found with this object", worldObject); return; } _clearWorld(world); const children = [...worldObject.children]; const newRBDIds = /* @__PURE__ */ new Set(); for (const child of children) { _physicsCreateRBD({ PhysicsLib: PhysicsLib2, world, rigidBodyById, objectsByRBD, object: child, newRBDIds }); } physicsCreateJoints(PhysicsLib2, world, worldObject); for (const child of children) { createOrFindPhysicsPlayer({ scene, object: child, PhysicsLib: PhysicsLib2, world, worldObject }); } } export function object3DFromRBD(rbd) { return objectsByRBD.get(rbd); } export function physicsCreateRBDFromWorldObject(worldObject, object) { const world = physicsWorldFromObject(worldObject); if (!world) { console.warn("no physicsWorld found with this object", worldObject); return; } return physicsCreateRBDFromWorld(world, object); } export function physicsCreateRBDFromWorld(world, object) { const PhysicsLib2 = CorePhysicsLoaded(); if (!PhysicsLib2) { return; } const newRBDIds = /* @__PURE__ */ new Set(); _physicsCreateRBD({ PhysicsLib: PhysicsLib2, world, rigidBodyById, objectsByRBD, object, newRBDIds }); return newRBDIds; } export function getRBDFromId(rbdId) { return rigidBodyById.get(rbdId); } function _clearWorld(world) { const bodies = []; const colliders = []; const joints = []; const multiBodyJoints = []; world.bodies.forEach((body) => { bodies.push(body); }); world.colliders.forEach((collider) => { colliders.push(collider); }); world.impulseJoints.forEach((joint) => { joints.push(joint); }); world.multibodyJoints.forEach((multiBodyJoint) => { multiBodyJoints.push(multiBodyJoint); }); for (const body of bodies) { world.removeRigidBody(body); } for (const collider of colliders) { world.removeCollider(collider, false); } for (const joint of joints) { world.removeImpulseJoint(joint, false); } for (const joint of multiBodyJoints) { world.removeMultibodyJoint(joint, false); } clearPhysicsPlayers(); } export function stepWorld(worldObject) { const world = physicsWorldFromObject(worldObject); if (!world) { return; } world.step(); world.bodies.forEach((body) => { const object = objectsByRBD.get(body); if (object) { physicsUpdateRBD(object, body); } }); } const currentGravity = new Vector3(); const newGravity = new Vector3(); export function setWorldGravity(worldObject, gravity, lerp) { const world = physicsWorldFromObject(worldObject); if (!world) { return; } if (lerp < 1) { currentGravity.set(world.gravity.x, world.gravity.y, world.gravity.z); newGravity.copy(gravity); currentGravity.lerp(newGravity, lerp); } world.gravity.x = gravity.x; world.gravity.y = gravity.y; world.gravity.z = gravity.z; }