1 | const numsegmentstube = 1; |
---|
2 | |
---|
3 | /** |
---|
4 | * Helper class for creating meshes for joints in Framsticks-SDK. It combines |
---|
5 | * Framsticks-SDK logic with THREE.js logic. |
---|
6 | * |
---|
7 | * For now shape versions of joints are hard-coded. It may need redefinition in |
---|
8 | * the future. |
---|
9 | */ |
---|
10 | class JointMeshFactory { |
---|
11 | /** |
---|
12 | * Basic constructor that takes information of how joints should be drawn. |
---|
13 | * @param {object} config basic config for joints drawing |
---|
14 | * @param {object} cylinderShape object holding following fields |
---|
15 | * @param {number} cylinderShape.radius radius of mesh |
---|
16 | * @param {number} cylinderShape.radiusSegments number of segments for mesh |
---|
17 | * @param {boolean} cylinderShape.isTransparent true if transparent, false otherwise |
---|
18 | * @param {number} cylinderShape.opacity opacity of mesh |
---|
19 | * @param {object} linkShape object holding following fields |
---|
20 | * @param {number} linkShape.radius radius of mesh |
---|
21 | * @param {number} linkShape.radiusSegments number of segments for mesh |
---|
22 | * @param {boolean} linkShape.isTransparent true if transparent, false otherwise |
---|
23 | * @param {number} linkShape.opacity opacity of mesh |
---|
24 | */ |
---|
25 | constructor(config) { |
---|
26 | this.config = config; |
---|
27 | this.transformations = new ShapeTransformations(); |
---|
28 | this.jointShapes = this.transformations.getJointShapes(); |
---|
29 | } |
---|
30 | |
---|
31 | /** |
---|
32 | * Creates Mesh for a given Joint. |
---|
33 | * @param {Module.Joint} joint Framsticks-SDK Joint class object |
---|
34 | * @param {object} shapeConfig object holding following fields |
---|
35 | * @param {number} shapeConfig.radius radius of mesh |
---|
36 | * @param {number} shapeConfig.radiusSegments number of segments for mesh |
---|
37 | * @param {boolean} shapeConfig.isTransparent true if transparent, false otherwise |
---|
38 | * @param {number} shapeConfig.opacity opacity of mesh |
---|
39 | * @returns {Mesh} Mesh for a given joint |
---|
40 | */ |
---|
41 | getNewJointMesh(joint, shapeConfig) { |
---|
42 | let firstPartPosVec = new THREE.Vector3( |
---|
43 | joint.get_part1().get_p().get_x(), |
---|
44 | joint.get_part1().get_p().get_y(), |
---|
45 | joint.get_part1().get_p().get_z()); |
---|
46 | let secondPartPosVec = new THREE.Vector3( |
---|
47 | joint.get_part2().get_p().get_x(), |
---|
48 | joint.get_part2().get_p().get_y(), |
---|
49 | joint.get_part2().get_p().get_z()); |
---|
50 | let line = new THREE.LineCurve3(firstPartPosVec, secondPartPosVec); |
---|
51 | let geometry = new THREE.TubeGeometry(line, numsegmentstube, shapeConfig.radius, |
---|
52 | shapeConfig.radiusSegments, false); |
---|
53 | |
---|
54 | let material = this.transformations.getNewMaterial( |
---|
55 | joint.get_vcolor().get_x(), |
---|
56 | joint.get_vcolor().get_y(), |
---|
57 | joint.get_vcolor().get_z()); |
---|
58 | material.transparent = shapeConfig.isTransparent; |
---|
59 | material.opacity = shapeConfig.opacity; |
---|
60 | let mesh = new THREE.Mesh(geometry, material); |
---|
61 | mesh.userData = { |
---|
62 | isBodyElement: true, |
---|
63 | type: 'j', |
---|
64 | data: joint, |
---|
65 | mesh: mesh, |
---|
66 | connectedParts: [], |
---|
67 | showTransparent: shapeConfig.isTransparent |
---|
68 | }; |
---|
69 | return mesh; |
---|
70 | } |
---|
71 | |
---|
72 | /** |
---|
73 | * Method finds for a given jointMesh all attached partMeshes and updates |
---|
74 | * respectively for those objects their connectedParts and connectedJoints |
---|
75 | * fields. |
---|
76 | * @param {JointMesh} jointMesh joint for which attached parts will be searched |
---|
77 | * @param {PartMesh} partMeshes list of available parts |
---|
78 | */ |
---|
79 | addConnectionInfo(jointMesh, partMeshes) { |
---|
80 | let p1 = jointMesh.data.get_part1(); |
---|
81 | let p2 = jointMesh.data.get_part2(); |
---|
82 | let count = 0; |
---|
83 | for (let i = 0; i < partMeshes.length && count < 2; ++i) { |
---|
84 | if (partMeshes[i].data === p1 || partMeshes[i].data === p2) { |
---|
85 | jointMesh.connectedParts.push(partMeshes[i]); |
---|
86 | partMeshes[i].connectedJoints.push(jointMesh); |
---|
87 | ++count; |
---|
88 | } |
---|
89 | } |
---|
90 | } |
---|
91 | |
---|
92 | /** |
---|
93 | * Creates mesh for a given Joint. Additional parameter partMeshes is |
---|
94 | * provided to update both Joint and connected Parts with info about |
---|
95 | * their connectivity. |
---|
96 | * @param {Module.Joint} joint joint for which mesh is created |
---|
97 | * @param {PartMesh} partMeshes list of available parts |
---|
98 | * @returns {JointMesh} new joint mesh, for properties of Object look at addConnectionInfo jointMesh param documentation |
---|
99 | */ |
---|
100 | create(joint, partMeshes) { |
---|
101 | let result; |
---|
102 | let shape = joint.get_shape(); |
---|
103 | |
---|
104 | if (this.jointShapes['SHAPE_FIXED'].value == shape) { |
---|
105 | result = this.getNewJointMesh(joint, this.config.linkShape); |
---|
106 | } else { |
---|
107 | result = this.getNewJointMesh(joint, this.config.cylinderShape); |
---|
108 | } |
---|
109 | |
---|
110 | if (partMeshes) { |
---|
111 | this.addConnectionInfo(result.userData, partMeshes); |
---|
112 | } |
---|
113 | |
---|
114 | return result; |
---|
115 | } |
---|
116 | } |
---|