playcanvas
Version:
Open-source WebGL/WebGPU 3D engine for the web
67 lines (66 loc) • 2.65 kB
JavaScript
import { Vec2 } from "../../core/math/vec2.js";
import { CapsuleGeometry } from "../../scene/geometry/capsule-geometry.js";
import { ConeGeometry } from "../../scene/geometry/cone-geometry.js";
import { CylinderGeometry } from "../../scene/geometry/cylinder-geometry.js";
import { TorusGeometry } from "../../scene/geometry/torus-geometry.js";
import { Mesh } from "../../scene/mesh.js";
import { BoxGeometry } from "../../scene/geometry/box-geometry.js";
import { SphereGeometry } from "../../scene/geometry/sphere-geometry.js";
import { PlaneGeometry } from "../../scene/geometry/plane-geometry.js";
import { DeviceCache } from "../../platform/graphics/device-cache.js";
class PrimitivesCache {
map = /* @__PURE__ */ new Map();
// destroy all created primitives when the device is destroyed
destroy(device) {
this.map.forEach((primData) => primData.mesh.destroy());
}
}
const _primitivesCache = new DeviceCache();
const getShapePrimitive = (device, type) => {
const cache = _primitivesCache.get(device, () => {
return new PrimitivesCache();
});
let primData = cache.map.get(type);
if (!primData) {
let mesh, area;
switch (type) {
case "box":
mesh = Mesh.fromGeometry(device, new BoxGeometry());
area = { x: 2, y: 2, z: 2, uv: 2 / 3 };
break;
case "capsule":
mesh = Mesh.fromGeometry(device, new CapsuleGeometry({ radius: 0.5, height: 2 }));
area = { x: Math.PI * 2, y: Math.PI, z: Math.PI * 2, uv: 1 / 3 + 1 / 3 / 3 * 2 };
break;
case "cone":
mesh = Mesh.fromGeometry(device, new ConeGeometry({ baseRadius: 0.5, peakRadius: 0, height: 1 }));
area = { x: 2.54, y: 2.54, z: 2.54, uv: 1 / 3 + 1 / 3 / 3 };
break;
case "cylinder":
mesh = Mesh.fromGeometry(device, new CylinderGeometry({ radius: 0.5, height: 1 }));
area = { x: Math.PI, y: 0.79 * 2, z: Math.PI, uv: 1 / 3 + 1 / 3 / 3 * 2 };
break;
case "plane":
mesh = Mesh.fromGeometry(device, new PlaneGeometry({ halfExtents: new Vec2(0.5, 0.5), widthSegments: 1, lengthSegments: 1 }));
area = { x: 0, y: 1, z: 0, uv: 1 };
break;
case "sphere":
mesh = Mesh.fromGeometry(device, new SphereGeometry({ radius: 0.5 }));
area = { x: Math.PI, y: Math.PI, z: Math.PI, uv: 1 };
break;
case "torus":
mesh = Mesh.fromGeometry(device, new TorusGeometry({ tubeRadius: 0.2, ringRadius: 0.3 }));
area = { x: Math.PI * 0.5 * 0.5 - Math.PI * 0.1 * 0.1, y: 0.4, z: 0.4, uv: 1 };
break;
default:
throw new Error(`Invalid primitive type: ${type}`);
}
mesh.incRefCount();
primData = { mesh, area };
cache.map.set(type, primData);
}
return primData;
};
export {
getShapePrimitive
};