mirror of
https://github.com/vercel-labs/scriptc.git
synced 2026-10-23 06:10:02 +08:00
* Expand static three.js workflows and host integration * Preserve JavaScript class state in static three.js workflows * Preserve inferred JavaScript behavior across static workflows * Preserve inferred callables and native compatibility boundaries * Retain annotated JavaScript factory exports and bootstrap-safe call spreads * Preserve Buffer and child callback identities in static packages * Clarify JavaScript symbol spread support
107 lines
4.6 KiB
JavaScript
107 lines
4.6 KiB
JavaScript
import { BatchedMesh, Bone, Box3, BoxGeometry, BufferGeometry, Color, Float32BufferAttribute, InstancedMesh, LOD, Matrix3, Matrix4, Mesh, MeshBasicMaterial, PerspectiveCamera, Ray, Raycaster, Skeleton, SkinnedMesh, Sprite, SpriteMaterial, Triangle, Uint16BufferAttribute, Vector3 } from "three";
|
|
import { clone } from "three/addons/utils/SkeletonUtils.js";
|
|
import { OBB } from "three/addons/math/OBB.js";
|
|
|
|
// instancing
|
|
{
|
|
const mesh = new InstancedMesh(new BoxGeometry(), new MeshBasicMaterial(), 2);
|
|
mesh.setMatrixAt(0, new Matrix4().makeTranslation(0, 0, -3));
|
|
mesh.setMatrixAt(1, new Matrix4().makeTranslation(2, 0, -3));
|
|
mesh.setColorAt(0, new Color(0xff0000));
|
|
mesh.setColorAt(1, new Color(0x00ff00));
|
|
const c = new Color();
|
|
mesh.getColorAt(1, c);
|
|
mesh.computeBoundingSphere();
|
|
mesh.updateMatrixWorld();
|
|
console.log('instance', c.g, mesh.boundingSphere.radius.toFixed(4));
|
|
const hits = new Raycaster(new Vector3(0.1, 0.1, 0), new Vector3(0, 0, -1)).intersectObject(mesh);
|
|
console.log('hit', hits.length, hits[0].instanceId, hits[0].object === mesh);
|
|
}
|
|
|
|
// batched-mesh
|
|
{
|
|
const batch = new BatchedMesh(4, 100, 200, new MeshBasicMaterial());
|
|
const id = batch.addGeometry(new BoxGeometry());
|
|
const instance = batch.addInstance(id);
|
|
batch.setMatrixAt(instance, new Matrix4().makeTranslation(1, 2, 3));
|
|
batch.setColorAt(instance, new Color(0xff0000));
|
|
const m = new Matrix4();
|
|
batch.getMatrixAt(instance, m);
|
|
console.log('batch', instance, m.elements[12], batch.getVisibleAt(instance), batch.instanceCount);
|
|
}
|
|
|
|
// lod-sprite
|
|
{
|
|
const lod = new LOD(), a = new Mesh(new BoxGeometry(), new MeshBasicMaterial()), b = new Mesh(new BoxGeometry(), new MeshBasicMaterial());
|
|
lod.addLevel(a, 0).addLevel(b, 5);
|
|
const camera = new PerspectiveCamera();
|
|
camera.position.z = 10;
|
|
camera.updateMatrixWorld();
|
|
lod.update(camera);
|
|
console.log('lod', lod.getCurrentLevel(), a.visible, b.visible, lod.getObjectForDistance(2) === a);
|
|
const sprite = new Sprite(new SpriteMaterial());
|
|
sprite.position.z = -3;
|
|
sprite.updateMatrixWorld();
|
|
const ray = new Raycaster(new Vector3(), new Vector3(0, 0, -1));
|
|
ray.camera = camera;
|
|
console.log('sprite', ray.intersectObject(sprite).length);
|
|
}
|
|
|
|
// morph-targets
|
|
{
|
|
const g = new BufferGeometry();
|
|
g.setAttribute('position', new Float32BufferAttribute([0, 0, 0, 1, 0, 0, 0, 1, 0], 3));
|
|
g.morphAttributes.position = [new Float32BufferAttribute([0, 0, 1, 1, 0, 1, 0, 1, 1], 3)];
|
|
const mesh = new Mesh(g, new MeshBasicMaterial());
|
|
mesh.morphTargetInfluences[0] = 0.5;
|
|
console.log('morph', mesh.morphTargetInfluences.length, mesh.getVertexPosition(0, new Vector3()).z);
|
|
g.computeBoundingBox();
|
|
console.log('bounds', g.boundingBox.max.z);
|
|
}
|
|
|
|
// skeleton-skinning
|
|
{
|
|
const g = new BufferGeometry();
|
|
g.setAttribute('position', new Float32BufferAttribute([0, 0, 0], 3));
|
|
g.setAttribute('skinIndex', new Uint16BufferAttribute([0, 0, 0, 0], 4));
|
|
g.setAttribute('skinWeight', new Float32BufferAttribute([1, 0, 0, 0], 4));
|
|
const bone = new Bone(), skeleton = new Skeleton([bone]);
|
|
const mesh = new SkinnedMesh(g, new MeshBasicMaterial());
|
|
mesh.add(bone);
|
|
mesh.bind(skeleton, new Matrix4());
|
|
bone.position.y = 2;
|
|
mesh.updateMatrixWorld(true);
|
|
skeleton.update();
|
|
console.log('skin', mesh.getVertexPosition(0, new Vector3()).y, skeleton.boneMatrices[13], skeleton.clone().bones.length);
|
|
mesh.normalizeSkinWeights();
|
|
console.log('weight', g.attributes.skinWeight.getX(0));
|
|
}
|
|
|
|
// skeleton-utils
|
|
{
|
|
const root = new Bone(), child = new Bone();
|
|
root.add(child);
|
|
const mesh = new SkinnedMesh(new BoxGeometry(), new MeshBasicMaterial());
|
|
mesh.add(root);
|
|
mesh.bind(new Skeleton([root, child]));
|
|
const copy = clone(mesh);
|
|
console.log('clone', copy !== mesh, copy.skeleton !== mesh.skeleton, copy.skeleton.bones[0] !== root, copy.skeleton.bones[0] === copy.children[0]);
|
|
}
|
|
|
|
// mesh-attribute-missing-w
|
|
{
|
|
const a = new Float32BufferAttribute([1, 0, 0, 0, 1, 0, 0, 0, 1], 3);
|
|
const v = Triangle.getInterpolatedAttribute(a, 0, 1, 2, new Vector3(0.5, 0.25, 0.25), new Vector3());
|
|
console.log(v.x, v.y, v.z);
|
|
}
|
|
|
|
// collision-obb
|
|
{
|
|
const a = new OBB(new Vector3(), new Vector3(1, 1, 1), new Matrix3());
|
|
const b = new OBB(new Vector3(1, 0, 0), new Vector3(1, 1, 1), new Matrix3());
|
|
console.log('obb', a.intersectsOBB(b), a.containsPoint(new Vector3(0.5, 0, 0)));
|
|
b.center.x = 5;
|
|
console.log('miss', a.intersectsOBB(b));
|
|
console.log('ray', a.intersectRay(new Ray(new Vector3(0, 0, 5), new Vector3(0, 0, -1)), new Vector3()).z);
|
|
}
|