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

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

Initial, prototype version of a javascript app to test how humans align two 3D structures

File size: 5.2 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, 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        //let line = new THREE.LineCurve3(firstPartPosVec, secondPartPosVec);
45        //let geometry = new THREE.TubeGeometry(line, numsegmentstube, shapeConfig.radius,
46        //    shapeConfig.radiusSegments, false);
47
48        let direction = new THREE.Vector3().subVectors(secondPartPosVec, firstPartPosVec);
49        let orientation = new THREE.Matrix4();
50
51        let geometry = new THREE.CylinderGeometry(shapeConfig.radius, shapeConfig.radius, direction.length(), shapeConfig.radiusSegments);
52       
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       
62        let mesh = new THREE.Mesh( geometry, material ); //new Physijs.CylinderMesh( geometry, Physijs.createMaterial(material) ); //new THREE.Mesh( geometry, material );
63
64        orientation.lookAt(firstPartPosVec, secondPartPosVec, new THREE.Object3D().up);
65        orientation.multiply(new THREE.Matrix4().set(
66            1, 0, 0, 0,
67            0, 0, 1, 0,
68            0, -1, 0, 0,
69            0, 0, 0, 1
70        ));
71
72        mesh.applyMatrix(orientation);
73        mesh.position.x = (secondPartPosVec.x + firstPartPosVec.x) / 2;
74        mesh.position.y = (secondPartPosVec.y + firstPartPosVec.y) / 2;
75        mesh.position.z = (secondPartPosVec.z + firstPartPosVec.z) / 2;
76       
77       
78        mesh.userData = {
79            isBodyElement: true,
80            type: 'j',
81            data: joint,
82            mesh: mesh,
83            connectedParts: [],
84            showTransparent: shapeConfig.isTransparent
85        };
86        return mesh;
87    }
88
89    /**
90     * Method finds for a given jointMesh all attached partMeshes and updates
91     * respectively for those objects their connectedParts and connectedJoints
92     * fields.
93     * @param {JointMesh}  jointMesh joint for which attached parts will be searched
94     * @param {PartMesh}  partMeshes list of available parts
95     */
96    addConnectionInfo(jointMesh, partMeshes) {
97        let p1 = jointMesh.data.get_part1();
98        let p2 = jointMesh.data.get_part2();
99        let count = 0;
100        for (let i = 0; i < partMeshes.length && count < 2; ++i) {
101            if (partMeshes[i].data === p1 || partMeshes[i].data === p2) {
102                jointMesh.connectedParts.push(partMeshes[i]);
103                partMeshes[i].connectedJoints.push(jointMesh);
104                ++count;
105            }
106        }
107    }
108
109    /**
110     * Creates mesh for a given Joint. Additional parameter partMeshes is
111     * provided to update both Joint and connected Parts with info about
112     * their connectivity.
113     * @param {Module.Joint} joint joint for which mesh is created
114     * @param {PartMesh}  partMeshes list of available parts
115     * @returns {JointMesh} new joint mesh, for properties of Object look at addConnectionInfo jointMesh param documentation
116     */
117    create(joint, partMeshes) {
118        let result;
119        let shape = joint.get_shape();
120
121        if (this.jointShapes['SHAPE_FIXED'].value == shape) {
122            result = this.getNewJointMesh(joint, this.config.linkShape);
123        } else {
124            result = this.getNewJointMesh(joint, this.config.cylinderShape);
125        }
126
127        if (partMeshes) {
128            this.addConnectionInfo(result.userData, partMeshes);
129        }
130
131        return result;
132    }
133}
134
135export default JointMeshFactory;
Note: See TracBrowser for help on using the repository browser.