add physics to interactive objects

This commit is contained in:
2025-11-08 17:08:51 +02:00
parent 168fb5b770
commit f5a08a9702
10 changed files with 67 additions and 36 deletions
+24 -6
View File
@@ -1,4 +1,4 @@
import { TextureLoader, Box3, Vector3 } from "three";
import { TextureLoader, Box3, Vector3, Group } from "three";
function assignParams(mesh, params){
['scale', 'rotation', 'position'].forEach(p=>params[p] && mesh[p].fromArray(params[p]));
@@ -30,16 +30,22 @@ function getBoundingBox(object){
return new Box3().setFromObject(object);
}
function getBoundingBoxSize(bb){
return new Vector3(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z);
}
function getBoundingBoxMaxLength(bb){
return Math.max(bb.max.x - bb.min.x, bb.max.y - bb.min.y, bb.max.z - bb.min.z)
let size = getBoundingBoxSize(bb)
return Math.max(size.x, size.y, size.z)
}
function getBoundingBoxCenterPoint(bb, relativeTo){
relativeTo = relativeTo || new Vector3(0,0,0)
let size = getBoundingBoxSize(bb)
return new Vector3(
bb.min.x + (bb.max.x - bb.min.x)/2 - relativeTo.x,
bb.min.y + (bb.max.y - bb.min.y)/2 - relativeTo.y,
bb.min.z + (bb.max.z - bb.min.z)/2 - relativeTo.z
bb.min.x + (size.x)/2 - relativeTo.x,
bb.min.y + (size.y)/2 - relativeTo.y,
bb.min.z + (size.z)/2 - relativeTo.z
)
}
@@ -49,4 +55,16 @@ function autoScale(object, mk = 1) {
object.scale.multiplyScalar(mk / k);
}
export { assignParams, assignMaterial, autoScale, getBoundingBox, getBoundingBoxMaxLength, getBoundingBoxCenterPoint }
function centerOrigin(object){
let result = new Group();
let bb = getBoundingBox(object);
let position = getBoundingBoxCenterPoint(bb, object.position).negate();
object.position.copy(position)
result.add(object);
return result;
}
export {
assignParams, assignMaterial, autoScale, centerOrigin,
getBoundingBox, getBoundingBoxSize, getBoundingBoxMaxLength, getBoundingBoxCenterPoint
}
+7 -11
View File
@@ -20,9 +20,10 @@ class Physics{
return this;
}
add = (mesh, rigidBodyType, autoAnimate = true, postPhysicsFn, colliderType, colliderSettings) => {
add = (mesh, rigidBodyType, autoAnimate = true, postPhysicsFn, colliderType, colliderSettings = {}) => {
const rigidBodyDesc = RAPIER.RigidBodyDesc[rigidBodyType]()
rigidBodyDesc.setTranslation(mesh.position.x, mesh.position.y, mesh.position.z)
mesh.quaternion && rigidBodyDesc.setRotation(mesh.quaternion)
// * Responsible for collision response
const rigidBody = this.world.createRigidBody(rigidBodyDesc)
@@ -70,6 +71,7 @@ class Physics{
// * Responsible for collision detection
const collider = this.world.createCollider(colliderDesc, rigidBody)
mesh.quaternion && collider.setRotationWrtParent(mesh.quaternion)
const physicsObject = { mesh, collider, rigidBody, fn: postPhysicsFn, autoAnimate }
this.physicsObjects.push(physicsObject)
@@ -89,17 +91,11 @@ class Physics{
this.world.step(this.eventQueue)
for (let po of this.physicsObjects) {
const autoAnimate = po.autoAnimate
if (autoAnimate) {
const mesh = po.mesh
const collider = po.collider
mesh.position.copy(collider.translation())
mesh.quaternion.copy(collider.rotation() )
if (po.autoAnimate) {
po.mesh.position.copy(po.rigidBody.translation())
po.mesh.quaternion.copy(po.rigidBody.rotation() )
}
const fn = po.fn
fn && fn()
po.fn?.()
}
this.eventQueue.drainCollisionEvents((handle1, handle2, started) => {