forked from bostongfx/cs460student_2022
-
Notifications
You must be signed in to change notification settings - Fork 0
/
helper.js
83 lines (60 loc) · 2.2 KB
/
helper.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
HELPER = {}; // create a new instance
/**
* This method returns [geometry, material, bones] to create a skeleton mesh
* based on a cylinder.
*
* @param howmany: Number of bones.
* @param howwide: Radius of the cylinder.
* @param color: Color of the cylinder.
*/
HELPER.cylinderSkeletonMesh = function(howmany, howwide, color) {
var segmentheight = 10; // just a temporary value but it needs to match for geometry and bones
var height = segmentheight * howmany;
//
// inspired by https://threejs.org/docs/scenes/bones-browser.html
//
// step1: geometry
var geometry = new THREE.CylinderBufferGeometry(
howwide, // radiusTop
howwide, // radiusBottom
height, // height
8, // radiusSegments
howmany * 3, // heightSegments
true // openEnded
);
var position = geometry.attributes.position;
var vertex = new THREE.Vector3();
var skinIndices = [];
var skinWeights = [];
for ( var i = 0; i < position.count; i ++ ) {
vertex.fromBufferAttribute( position, i );
var y = ( vertex.y + height / 2 );
var skinIndex = Math.floor( y / segmentheight );
var skinWeight = ( y % segmentheight ) / segmentheight;
skinIndices.push( skinIndex, skinIndex + 1, 0, 0 );
skinWeights.push( 1 - skinWeight, skinWeight, 0, 0 );
}
geometry.setAttribute( 'skinIndex', new THREE.Uint16BufferAttribute( skinIndices, 4 ) );
geometry.setAttribute( 'skinWeight', new THREE.Float32BufferAttribute( skinWeights, 4 ) );
// step 2: setup material
var material = new THREE.MeshStandardMaterial( {
skinning: true, // IMPORTANT!
color: color,
side: THREE.DoubleSide,
flatShading: true
} );
// step 3: setup bones
var bones = [];
// we always need a dummy parent bone as the anchor point
var parentbone = new THREE.Bone();
// parentbone.position.y = -height / 2; // weeeeird
bones.push(parentbone);
for (var i=0; i< howmany; i++) {
var currentbone = new THREE.Bone();
currentbone.position.y = segmentheight;
parentbone.add(currentbone);
bones.push(currentbone); // add the bone
parentbone = currentbone;
}
return [geometry, material, bones];
};