@c-frame/aframe-physics-system
Version:
Physics system for A-Frame VR, built on Cannon.js & Ammo.js
103 lines (90 loc) • 2.76 kB
JavaScript
/* global Ammo,THREE */
const threeToAmmo = require("three-to-ammo");
const CONSTANTS = require("../../constants"),
SHAPE = CONSTANTS.SHAPE,
FIT = CONSTANTS.FIT;
var AmmoShape = {
schema: {
type: {
default: SHAPE.HULL,
oneOf: [
SHAPE.BOX,
SHAPE.CYLINDER,
SHAPE.SPHERE,
SHAPE.CAPSULE,
SHAPE.CONE,
SHAPE.HULL,
SHAPE.HACD,
SHAPE.VHACD,
SHAPE.MESH,
SHAPE.HEIGHTFIELD
]
},
fit: { default: FIT.ALL, oneOf: [FIT.ALL, FIT.MANUAL] },
halfExtents: { type: "vec3", default: { x: 1, y: 1, z: 1 } },
minHalfExtent: { default: 0 },
maxHalfExtent: { default: Number.POSITIVE_INFINITY },
sphereRadius: { default: NaN },
cylinderAxis: { default: "y", oneOf: ["x", "y", "z"] },
margin: { default: 0.01 },
offset: { type: "vec3", default: { x: 0, y: 0, z: 0 } },
orientation: { type: "vec4", default: { x: 0, y: 0, z: 0, w: 1 } },
heightfieldData: { default: [] },
heightfieldDistance: { default: 1 },
includeInvisible: { default: false }
},
multiple: true,
init: function() {
if (this.data.fit !== FIT.MANUAL) {
if (this.el.object3DMap.mesh) {
this.mesh = this.el.object3DMap.mesh;
} else {
const self = this;
this.el.addEventListener("object3dset", function (e) {
if (e.detail.type === "mesh") {
self.init();
}
});
console.log("Cannot use FIT.ALL without object3DMap.mesh. Waiting for it to be set.");
return;
}
}
this.system = this.el.sceneEl.systems.physics;
this.collisionShapes = [];
let bodyEl = this.el;
this.body = bodyEl.components["ammo-body"] || null;
while (!this.body && bodyEl.parentNode != this.el.sceneEl) {
bodyEl = bodyEl.parentNode;
if (bodyEl.components["ammo-body"]) {
this.body = bodyEl.components["ammo-body"];
}
}
if (!this.body) {
console.warn("body not found");
return;
}
this.body.addShapeComponent(this);
},
getMesh: function() {
return this.mesh || null;
},
addShapes: function(collisionShapes) {
this.collisionShapes = collisionShapes;
},
getShapes: function() {
return this.collisionShapes;
},
remove: function() {
if (!this.body) {
return;
}
this.body.removeShapeComponent(this);
while (this.collisionShapes.length > 0) {
const collisionShape = this.collisionShapes.pop();
collisionShape.destroy();
Ammo.destroy(collisionShape.localTransform);
}
}
};
module.exports.definition = AmmoShape;
module.exports.Component = AFRAME.registerComponent("ammo-shape", AmmoShape);