tassetloader
v1.0.1
Published
[](https://www.npmjs.com/package/tassetloader) [](https://www.gnu.org/licenses/lgpl-3.0.html)
Downloads
13
Readme
TassetLoader 🚀
tassetloader is a high-performance developer library designed to load, parse, and instantiate optimized .tasset files in Three.js environments. It acts as the bridging runtime package for assets generated by your .tasset compiler and optimizer tool.
By packing meshes, texture hierarchies, Level of Detail (LOD) configurations, and pre-computed physics bounds directly into a unified .tasset container, this loader minimizes loading times, handles texture transcoding out of the box, and generates stable physics colliders with zero runtime computational overhead.
🌟 Key Advantages
- ⚡ Ultra-Fast Load Times: Loads complex 3D assets, materials, and transcoded textures in a single request.
- 📐 Automatic LOD Setup: Re-constructs Three.js
LOD(Level of Detail) hierarchies automatically based on pre-compiled asset metadata. - 🛡️ Zero-Cost Physics Colliders: Extracts pre-generated Axis-Aligned Bounding Box (AABB) data and Convex Hull vertices directly from the file, avoiding expensive runtime collision geometry generation.
- 🌳 Tree-Shakable & Modular: Features separate subpath exports for Three.js physics integrations to keep production bundles tiny:
tassetloader/cannon(for Cannon-ES)tassetloader/rapier(for Rapier3D WASM)tassetloader/jolt(for Jolt Physics WASM/NPM)
📦 Installation
Install the package via npm:
npm install tassetloaderPeer Dependencies
To keep the bundle lightweight, Three.js and the physics engines are marked as optional peer dependencies. Install only the libraries you plan to use in your project:
# Core dependency (Required)
npm install three
# Physics engines (Optional - install what you need)
npm install cannon-es # For Cannon-ES physics
npm install @dimforge/rapier3d-compat # For Rapier3D WASM physics
npm install jolt-physics # For Jolt Physics NPM package🚀 Quick Start (Three.js Setup)
Configure the KTX2Loader (for texture transcoding) and load a .tasset model:
import * as THREE from 'three';
import { TassetLoader } from 'tassetloader';
import { KTX2Loader } from 'three/examples/jsm/loaders/KTX2Loader.js';
// 1. Setup Three.js Renderer
const renderer = new THREE.WebGLRenderer({ antialias: true });
document.body.appendChild(renderer.domElement);
// 2. Configure KTX2 texture transcoder path
const ktx2Loader = new KTX2Loader();
ktx2Loader.setTranscoderPath('/basis/'); // Path to transcoder scripts
ktx2Loader.detectSupport(renderer);
// 3. Register KTX2 Loader with TassetLoader
TassetLoader.setKTX2Loader(ktx2Loader);
// 4. Load the asset
const { group, metadata } = await TassetLoader.load('/models/chair.tasset');
scene.add(group);
console.log('Model loaded successfully!', group);
console.log('Pre-computed Physics Metadata:', metadata);🛠️ Physics Engine Integrations (Subpaths)
Instead of importing physics helper functions from the main package, import them from their respective modular subpaths to keep your production bundles optimized.
1. Cannon-ES Integration (tassetloader/cannon)
Creates a physics CANNON.Body representing either an AABB box or a compound of pre-computed convex hulls, and syncs it with a wrapping Three.js group.
import * as THREE from 'three';
import * as CANNON from 'cannon-es';
import { TassetLoader } from 'tassetloader';
import { createAABBBody, createHullBody } from 'tassetloader/cannon';
const world = new CANNON.World({ gravity: new CANNON.Vec3(0, -9.82, 0) });
const { group } = await TassetLoader.load('/chair.tasset');
// Create an Axis-Aligned Bounding Box (AABB) physics body
const aabbSim = createAABBBody(
world,
group, // Model containing pre-computed AABB metadata
new THREE.Vector3(-2, 5, 0), // Position
group.clone(), // Visual mesh wrapper
{ mass: 1, linearDamping: 0.4 }
);
scene.add(aabbSim.wrapper);
// Sync visual models with physics positions in your animation loop
function tick() {
world.fixedStep();
aabbSim.wrapper.position.copy(aabbSim.body.interpolatedPosition as any);
aabbSim.wrapper.quaternion.copy(aabbSim.body.interpolatedQuaternion as any);
}2. Rapier3D Integration (tassetloader/rapier)
Creates a RAPIER.RigidBody and sets up the corresponding colliders (cuboids or convex hulls) inside the Rapier simulation.
import * as THREE from 'three';
import RAPIER from '@dimforge/rapier3d-compat';
import { TassetLoader } from 'tassetloader';
import { createAABBRapierBody } from 'tassetloader/rapier';
await RAPIER.init();
const world = new RAPIER.World({ x: 0.0, y: -9.82, z: 0.0 });
const { group } = await TassetLoader.load('/chair.tasset');
const aabbSim = createAABBRapierBody(
world,
group,
new THREE.Vector3(-2, 5, 0),
group.clone(),
{ mass: 1, allowSleep: true }
);
scene.add(aabbSim.wrapper);
// Sync in animation loop
function tick() {
world.step();
const pos = aabbSim.body.translation();
const rot = aabbSim.body.rotation();
aabbSim.wrapper.position.set(pos.x, pos.y, pos.z);
aabbSim.wrapper.quaternion.set(rot.x, rot.y, rot.z, rot.w);
}3. Jolt Physics Integration (tassetloader/jolt)
Integrates seamlessly with either your custom multithreaded WASM builds or the official jolt-physics package.
import * as THREE from 'three';
import { TassetLoader } from 'tassetloader';
import { createAABBJoltBody } from 'tassetloader/jolt';
import initJolt from 'jolt-physics';
const jolt = await initJolt();
// 1. Configure Jolt collision layers
const LAYER_NON_MOVING = 0;
const LAYER_MOVING = 1;
const NUM_LAYERS = 2;
// Enable collision between non-moving vs moving, and moving vs moving objects
const objVsObjFilter = new jolt.ObjectLayerPairFilterTable(NUM_LAYERS);
objVsObjFilter.EnableCollision(LAYER_NON_MOVING, LAYER_MOVING);
objVsObjFilter.EnableCollision(LAYER_MOVING, LAYER_MOVING);
const BP_LAYER_NON_MOVING = new jolt.BroadPhaseLayer(0);
const BP_LAYER_MOVING = new jolt.BroadPhaseLayer(1);
const NUM_BP_LAYERS = 2;
const bpLayerInterface = new jolt.BroadPhaseLayerInterfaceTable(NUM_LAYERS, NUM_BP_LAYERS);
bpLayerInterface.MapObjectToBroadPhaseLayer(LAYER_NON_MOVING, BP_LAYER_NON_MOVING);
bpLayerInterface.MapObjectToBroadPhaseLayer(LAYER_MOVING, BP_LAYER_MOVING);
const objVsBpFilter = new jolt.ObjectVsBroadPhaseLayerFilterTable(
bpLayerInterface,
NUM_BP_LAYERS,
objVsObjFilter,
NUM_LAYERS
);
// 2. Initialize the Jolt Settings & Interface
const settings = new jolt.JoltSettings();
settings.mObjectLayerPairFilter = objVsObjFilter;
settings.mObjectVsBroadPhaseLayerFilter = objVsBpFilter;
settings.mBroadPhaseLayerInterface = bpLayerInterface;
const joltInterface = new jolt.JoltInterface(settings);
const bodyInterface = joltInterface.GetPhysicsSystem().GetBodyInterface();
// Clean up temporary setup settings
jolt.destroy(settings);
// 3. Load the model and create a Jolt physics body
const { group } = await TassetLoader.load('/chair.tasset');
const aabbSim = createAABBJoltBody(
jolt,
bodyInterface,
group,
new THREE.Vector3(-2, 5, 0),
group.clone(),
{ mass: 1 }
);
scene.add(aabbSim.wrapper);🎮 Running the Demo Locally
This repository includes a demo project in the demo/tassetdemo directory showcasing integrations with Cannon-ES, Rapier3D, and Jolt Physics.
To run the demo locally:
Build the main library at the project root:
npm run buildNavigate to the demo folder:
cd demo/tassetdemoInstall the dependencies:
npm installStart the development server:
npm run dev
Open http://localhost:5173 (or the URL displayed in your terminal) in your browser to see the loader and physics simulations in action.
📄 License
This project is licensed under the GNU Lesser General Public License v3.0 (LGPL-3.0-only). See the LICENSE file for the full terms.
