UNPKG

@osobh/reactar

Version:

AR Library for React Native and Expo

231 lines 8.99 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || (function () { var ownKeys = function(o) { ownKeys = Object.getOwnPropertyNames || function (o) { var ar = []; for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k; return ar; }; return ownKeys(o); }; return function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]); __setModuleDefault(result, mod); return result; }; })(); Object.defineProperty(exports, "__esModule", { value: true }); exports.PhysicsManager = void 0; // src/core/PhysicsManager.ts const AmmoModule = __importStar(require("ammojs3")); let ammoInstance; const three_1 = require("three"); const events_1 = require("events"); class PhysicsManager extends events_1.EventEmitter { constructor() { super(); this.objects = new Map(); this.isInitialized = false; this.gravity = new three_1.Vector3(0, -9.81, 0); this.timeStep = 1 / 60; } /** * Initializes the physics engine */ async initialize() { try { // Initialize Ammo.js const ammo = await AmmoModule.default(); // Assign to global Ammo variable globalThis.Ammo = ammo; this.collisionConfiguration = new Ammo.btDefaultCollisionConfiguration(); this.dispatcher = new Ammo.btCollisionDispatcher(this.collisionConfiguration); this.broadphase = new Ammo.btDbvtBroadphase(); this.solver = new Ammo.btSequentialImpulseConstraintSolver(); this.physicsWorld = new Ammo.btDiscreteDynamicsWorld(this.dispatcher, this.broadphase, this.solver, this.collisionConfiguration); // Set default gravity const gravity = new Ammo.btVector3(this.gravity.x, this.gravity.y, this.gravity.z); this.physicsWorld.setGravity(gravity); this.isInitialized = true; this.emit('initialized'); return true; } catch (error) { this.emit('error', error); throw error; } } /** * Creates a physics object and adds it to the physics world */ createObject(id, position, rotation, scale, properties = {}) { var _a, _b, _c, _d, _e; if (!this.isInitialized) { throw new Error('PhysicsManager must be initialized first'); } const transform = new Ammo.btTransform(); transform.setIdentity(); transform.setOrigin(new Ammo.btVector3(position.x, position.y, position.z)); transform.setRotation(new Ammo.btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); const motionState = new Ammo.btDefaultMotionState(transform); const shape = this.createBoxShape(scale); const mass = (_a = properties.mass) !== null && _a !== void 0 ? _a : 0; const localInertia = new Ammo.btVector3(0, 0, 0); if (mass > 0) { shape.calculateLocalInertia(mass, localInertia); } const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia); const body = new Ammo.btRigidBody(rbInfo); // Set additional properties body.setFriction((_b = properties.friction) !== null && _b !== void 0 ? _b : 0.5); body.setRestitution((_c = properties.restitution) !== null && _c !== void 0 ? _c : 0.2); body.setDamping((_d = properties.linearDamping) !== null && _d !== void 0 ? _d : 0.1, (_e = properties.angularDamping) !== null && _e !== void 0 ? _e : 0.1); if (properties.isKinematic) { body.setCollisionFlags(body.getCollisionFlags() | 2); // CF_KINEMATIC_OBJECT } this.physicsWorld.addRigidBody(body); this.objects.set(id, { id, body, mass, position: position.clone(), rotation: rotation.clone(), scale: scale.clone() }); this.emit('object-created', id); } /** * Updates the physics simulation */ update(deltaTime = this.timeStep) { if (!this.isInitialized) return; this.physicsWorld.stepSimulation(deltaTime, 10); // Update object positions and rotations this.objects.forEach((object) => { const transform = new Ammo.btTransform(); object.body.getMotionState().getWorldTransform(transform); const pos = transform.getOrigin(); const rot = transform.getRotation(); object.position.set(pos.x(), pos.y(), pos.z()); object.rotation.set(rot.x(), rot.y(), rot.z(), rot.w()); this.emit('object-updated', { id: object.id, position: object.position, rotation: object.rotation }); }); } /** * Applies a force to an object */ applyForce(id, force, point) { const object = this.objects.get(id); if (!object) { throw new Error(`Physics object ${id} not found`); } const btForce = new Ammo.btVector3(force.x, force.y, force.z); if (point) { const btPoint = new Ammo.btVector3(point.x, point.y, point.z); object.body.applyForce(btForce, btPoint); } else { object.body.applyCentralForce(btForce); } } /** * Sets the gravity of the physics world */ setGravity(gravity) { this.gravity = gravity.clone(); const btGravity = new Ammo.btVector3(gravity.x, gravity.y, gravity.z); this.physicsWorld.setGravity(btGravity); } /** * Creates a box collision shape */ createBoxShape(scale) { const shape = new Ammo.btBoxShape(new Ammo.btVector3(scale.x * 0.5, scale.y * 0.5, scale.z * 0.5)); return shape; } /** * Removes an object from the physics world */ removeObject(id) { const object = this.objects.get(id); if (!object) return; this.physicsWorld.removeRigidBody(object.body); this.objects.delete(id); this.emit('object-removed', id); } /** * Cleans up physics resources */ /** * Creates a rigid body with specified position, rotation and mass */ createRigidBody(position, rotation, mass) { if (!this.isInitialized) { throw new Error('PhysicsManager must be initialized first'); } const transform = new Ammo.btTransform(); transform.setIdentity(); transform.setOrigin(new Ammo.btVector3(position.x, position.y, position.z)); transform.setRotation(new Ammo.btQuaternion(rotation.x, rotation.y, rotation.z, rotation.w)); const motionState = new Ammo.btDefaultMotionState(transform); const shape = new Ammo.btBoxShape(new Ammo.btVector3(0.5, 0.5, 0.5)); const localInertia = new Ammo.btVector3(0, 0, 0); if (mass > 0) { shape.calculateLocalInertia(mass, localInertia); } const rbInfo = new Ammo.btRigidBodyConstructionInfo(mass, motionState, shape, localInertia); const body = new Ammo.btRigidBody(rbInfo); body.setMass(mass); this.physicsWorld.addRigidBody(body); return body; } /** * Gets the physics world instance */ getWorld() { if (!this.isInitialized) { throw new Error('PhysicsManager must be initialized first'); } return this.physicsWorld; } /** * Cleans up physics resources */ cleanup() { Array.from(this.objects.keys()).forEach(id => this.removeObject(id)); // Clean up Ammo.js resources Ammo.destroy(this.physicsWorld); Ammo.destroy(this.solver); Ammo.destroy(this.broadphase); Ammo.destroy(this.dispatcher); Ammo.destroy(this.collisionConfiguration); this.isInitialized = false; this.emit('cleanup-complete'); } } exports.PhysicsManager = PhysicsManager; //# sourceMappingURL=PhysicsManager.js.map