source: js/human_3d_alignment/src/visualization/jointmeshfactory.js @ 1081

Last change on this file since 1081 was 911, checked in by Maciej Komosinski, 5 years ago

Added the actual functionality of the app in place of previous draft

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