lingo3d
Version:
Lingo3D is a React/Vue 3d game development framework that ships with a complete visual editor
90 lines • 2.81 kB
JavaScript
import { Bone, SkinnedMesh, Skeleton, Vector3, CylinderGeometry, Uint16BufferAttribute, Float32BufferAttribute } from "three";
import { CCDIKSolver } from "three/examples/jsm/animation/CCDIKSolver";
import { standardMaterial } from "../display/utils/reusables";
import { onBeforeRender } from "../events/onBeforeRender";
import scene from "../engine/scene";
import { setSelectionTarget } from "../states/useSelectionTarget";
import SimpleObjectManager from "../display/core/SimpleObjectManager";
function createGeometry(sizing) {
const geometry = new CylinderGeometry(5, // radiusTop
5, // radiusBottom
sizing.height, // height
8, // radiusSegments
sizing.segmentCount * 1, // heightSegments
true // openEnded
);
const position = geometry.attributes.position;
const vertex = new Vector3();
const skinIndices = [];
const skinWeights = [];
for (let i = 0; i < position.count; i++) {
vertex.fromBufferAttribute(position, i);
const y = vertex.y + sizing.halfHeight;
const skinIndex = Math.floor(y / sizing.segmentHeight);
const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight;
skinIndices.push(skinIndex, skinIndex + 1, 0, 0);
skinWeights.push(1 - skinWeight, skinWeight, 0, 0);
}
geometry.setAttribute("skinIndex", new Uint16BufferAttribute(skinIndices, 4));
geometry.setAttribute("skinWeight", new Float32BufferAttribute(skinWeights, 4));
return geometry;
}
const segmentHeight = 8;
const segmentCount = 3;
const height = segmentHeight * segmentCount;
const halfHeight = height * 0.5;
const sizing = {
segmentHeight,
segmentCount,
height,
halfHeight
};
const geometry = createGeometry(sizing);
let ikSolver;
let bones = [];
// "root"
let rootBone = new Bone();
rootBone.position.y = -12;
bones.push(rootBone);
// "bone0"
let prevBone = new Bone();
prevBone.position.y = 0;
rootBone.add(prevBone);
bones.push(prevBone);
// "bone1", "bone2", "bone3"
for (let i = 1; i <= 3; i++) {
const bone = new Bone();
bone.position.y = 8;
bones.push(bone);
prevBone.add(bone);
prevBone = bone;
}
// "target"
const targetBone = new Bone();
targetBone.position.y = 24 + 8;
rootBone.add(targetBone);
bones.push(targetBone);
setSelectionTarget(new SimpleObjectManager(targetBone));
//
// skinned mesh
//
const mesh = new SkinnedMesh(geometry, standardMaterial);
scene.add(mesh);
const skeleton = new Skeleton(bones);
mesh.add(bones[0]); // "root" bone
mesh.bind(skeleton);
//
// ikSolver
//
const iks = [
{
target: 5,
effector: 4,
links: [{ index: 3 }, { index: 2 }, { index: 1 }] // "bone2", "bone1", "bone0"
}
];
ikSolver = new CCDIKSolver(mesh, iks);
onBeforeRender(() => {
ikSolver.update();
});
//# sourceMappingURL=testIK.js.map