UNPKG

6.44 kBTypeScriptView Raw
1import { BindMode } from "../constants.js";
2import { BufferGeometry } from "../core/BufferGeometry.js";
3import { JSONMeta, Object3DEventMap } from "../core/Object3D.js";
4import { Material } from "../materials/Material.js";
5import { Box3 } from "../math/Box3.js";
6import { Matrix4, Matrix4Tuple } from "../math/Matrix4.js";
7import { Sphere } from "../math/Sphere.js";
8import { Vector3 } from "../math/Vector3.js";
9import { Mesh, MeshJSON, MeshJSONObject } from "./Mesh.js";
10import { Skeleton } from "./Skeleton.js";
11
12export interface SkinnedMeshJSONObject extends MeshJSONObject {
13 bindMode: BindMode;
14 bindMatrix: Matrix4Tuple;
15 skeleton?: string;
16}
17
18export interface SkinnedMeshJSON extends MeshJSON {
19 object: SkinnedMeshJSONObject;
20}
21
22/**
23 * A mesh that has a {@link THREE.Skeleton | Skeleton} with {@link Bone | bones} that can then be used to animate the vertices of the geometry.
24 * @example
25 * ```typescript
26 * const geometry = new THREE.CylinderGeometry(5, 5, 5, 5, 15, 5, 30);
27 * // create the skin indices and skin weights manually
28 * // (typically a loader would read this data from a 3D model for you)
29 * const position = geometry.attributes.position;
30 * const vertex = new THREE.Vector3();
31 * const skinIndices = [];
32 * const skinWeights = [];
33 * for (let i = 0; i & lt; position.count; i++) {
34 * vertex.fromBufferAttribute(position, i);
35 * // compute skinIndex and skinWeight based on some configuration data
36 * const y = (vertex.y + sizing.halfHeight);
37 * const skinIndex = Math.floor(y / sizing.segmentHeight);
38 * const skinWeight = (y % sizing.segmentHeight) / sizing.segmentHeight;
39 * skinIndices.push(skinIndex, skinIndex + 1, 0, 0);
40 * skinWeights.push(1 - skinWeight, skinWeight, 0, 0);
41 * }
42 * geometry.setAttribute('skinIndex', new THREE.Uint16BufferAttribute(skinIndices, 4));
43 * geometry.setAttribute('skinWeight', new THREE.Float32BufferAttribute(skinWeights, 4));
44 * // create skinned mesh and skeleton
45 * const mesh = new THREE.SkinnedMesh(geometry, material);
46 * const skeleton = new THREE.Skeleton(bones);
47 * // see example from THREE.Skeleton
48 * const rootBone = skeleton.bones[0];
49 * mesh.add(rootBone);
50 * // bind the skeleton to the mesh
51 * mesh.bind(skeleton);
52 * // move the bones and manipulate the model
53 * skeleton.bones[0].rotation.x = -0.1;
54 * skeleton.bones[1].rotation.x = 0.2;
55 * ```
56 * @see {@link https://threejs.org/docs/index.html#api/en/objects/SkinnedMesh | Official Documentation}
57 * @see {@link https://github.com/mrdoob/three.js/blob/master/src/objects/SkinnedMesh.js | Source}
58 */
59export class SkinnedMesh<
60 TGeometry extends BufferGeometry = BufferGeometry,
61 TMaterial extends Material | Material[] = Material | Material[],
62 TEventMap extends Object3DEventMap = Object3DEventMap,
63> extends Mesh<TGeometry, TMaterial, TEventMap> {
64 /**
65 * Create a new instance of {@link SkinnedMesh}
66 * @param geometry An instance of {@link THREE.BufferGeometry | BufferGeometry}. Default {@link THREE.BufferGeometry | `new THREE.BufferGeometry()`}.
67 * @param material A single or an array of {@link THREE.Material | Material}. Default {@link THREE.MeshBasicMaterial | `new THREE.MeshBasicMaterial()`}.
68 */
69 constructor(geometry?: TGeometry, material?: TMaterial, useVertexTexture?: boolean);
70
71 /**
72 * Read-only flag to check if a given object is of type {@link SkinnedMesh}.
73 * @remarks This is a _constant_ value
74 * @defaultValue `true`
75 */
76 readonly isSkinnedMesh: true;
77
78 /**
79 * @override
80 * @defaultValue `SkinnedMesh`
81 */
82 override readonly type: string | "SkinnedMesh";
83
84 /**
85 * Either {@link AttachedBindMode} or {@link DetachedBindMode}. {@link AttachedBindMode} means the skinned mesh
86 * shares the same world space as the skeleton. This is not true when using {@link DetachedBindMode} which is useful
87 * when sharing a skeleton across multiple skinned meshes.
88 * @defaultValue `AttachedBindMode`
89 */
90 bindMode: BindMode;
91
92 /**
93 * The base matrix that is used for the bound bone transforms.
94 */
95 bindMatrix: Matrix4;
96 /**
97 * The base matrix that is used for resetting the bound bone transforms.
98 */
99 bindMatrixInverse: Matrix4;
100
101 /**
102 * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingBox | .computeBoundingBox()}.
103 * @default `null`
104 */
105 boundingBox: Box3;
106
107 /**
108 * The bounding box of the SkinnedMesh. Can be calculated with {@link computeBoundingSphere | .computeBoundingSphere()}.
109 * @default `null`
110 */
111 boundingSphere: Sphere;
112
113 /**
114 * {@link THREE.Skeleton | Skeleton} representing the bone hierarchy of the skinned mesh.
115 */
116 skeleton: Skeleton;
117
118 /**
119 * Bind a skeleton to the skinned mesh
120 * @remarks
121 * The bindMatrix gets saved to .bindMatrix property and the .bindMatrixInverse gets calculated.
122 * @param skeleton {@link THREE.Skeleton | Skeleton} created from a {@link Bone | Bones} tree.
123 * @param bindMatrix {@link THREE.Matrix4 | Matrix4} that represents the base transform of the skeleton.
124 */
125 bind(skeleton: Skeleton, bindMatrix?: Matrix4): void;
126
127 /**
128 * Computes the bounding box of the skinned mesh, and updates the {@link .boundingBox} attribute. The bounding box
129 * is not computed by the engine; it must be computed by your app. If the skinned mesh is animated, the bounding box
130 * should be recomputed per frame.
131 */
132 computeBoundingBox(): void;
133
134 /**
135 * Computes the bounding sphere of the skinned mesh, and updates the {@link .boundingSphere} attribute. The bounding
136 * sphere is automatically computed by the engine when it is needed, e.g., for ray casting and view frustum culling.
137 * If the skinned mesh is animated, the bounding sphere should be recomputed per frame.
138 */
139 computeBoundingSphere(): void;
140
141 /**
142 * This method sets the skinned mesh in the rest pose (resets the pose).
143 */
144 pose(): void;
145
146 /**
147 * Normalizes the skin weights.
148 */
149 normalizeSkinWeights(): void;
150
151 /**
152 * Applies the bone transform associated with the given index to the given position vector
153 * @remarks Returns the updated vector.
154 * @param index Expects a `Integer`
155 * @param vector
156 */
157 applyBoneTransform(index: number, vector: Vector3): Vector3;
158
159 toJSON(meta?: JSONMeta): SkinnedMeshJSON;
160}