source: js/human_3d_alignment/src/visualization/partmeshfactory.js @ 1302

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

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

File size: 6.6 KB
Line 
1"use strict";
2import * as THREE from 'three';
3import Transformations from './transformations';
4
5/**
6 * Helper class for creating meshes for parts in Framsticks-SDK.
7 * It combines Framsticks-SDK logic with THREE.js logic.
8 *
9 * For now shape versions of parts are hard-coded. It may need redefinition
10 * in the future.
11 */
12class PartMeshFactory {
13    /**
14     * Basic constructor that takes information of how parts should be drawn.
15     * @param {object} config object holding following fields
16     * @param {object} config.defaultShape object holding following fields
17     * @param {number} config.defaultShape.radius radius of part cylinder
18     * @param {number} config.defaultShape.segments number of segments on cylinder
19     * @param {object} config.ellipsoidShape object holding following fields
20     * @param {number} config.ellipsoidShape.radius radius of part ellipsoid
21     * @param {number} config.ellipsoidShape.segments number of segments on ellipsoid
22     *
23     */
24    constructor(config) {
25        this.config = config;
26        this.transformations = new Transformations();
27        this.partShapes = this.transformations.getPartShapes();
28    }
29
30    /**
31     * Creates sphere mesh for a given part.
32     * @param {Module.Part} part part, for which Mesh is generated
33     * @param {number} sphereRadius radius of part sphere
34     * @param {number} segments number of created segments
35     * @param {boolean} applyScale true if scale for this mesh should be applied from Module.Part
36     * @returns {PartMesh} info about part mesh
37     */
38    getNewSphereMesh(part, color, sphereRadius, segments, applyScale) {
39        let geometry = new THREE.SphereGeometry(sphereRadius, segments, segments);
40        let material = this.transformations.getNewMaterial(color);
41        let mesh = null;
42        if (applyScale) {
43            geometry.scale(
44                part.get_scale().get_x(),
45                part.get_scale().get_y(),
46                part.get_scale().get_z());
47            if (part.get_scale().get_x() == part.get_scale().get_y() &&
48                part.get_scale().get_x() == part.get_scale().get_z()) {
49                mesh = new THREE.Mesh(geometry, material);
50            } else {
51                mesh = new THREE.Mesh(geometry, material);
52            }
53        }
54        else {
55            mesh = new THREE.Mesh(geometry, material);
56        }
57        mesh.position.set(
58            part.get_p().get_x(),
59            part.get_p().get_y(),
60            part.get_p().get_z());
61
62        // if (applyScale) {
63        //     mesh.scale.set(
64        //         part.get_scale().get_x(),
65        //         part.get_scale().get_y(),
66        //         part.get_scale().get_z());
67        // }
68
69        let angles = part.get_o().getAngles();
70        mesh.rotation.copy(
71            this.transformations.getPartRotation(
72                angles.get_x(),
73                angles.get_y(),
74                angles.get_z())
75        );
76
77        mesh.userData = {
78            isBodyElement: true,
79            type: 'p',
80            data: part,
81            mesh: mesh,
82            isPhysical: this.physics,
83            connectedJoints: []
84        };
85        return mesh;
86    }
87
88    /**
89     * Creates box mesh for a given part
90     * @param {Module.Part} part part, for which Mesh is generated
91     * @returns {PartMesh} info about part mesh
92     */
93    getNewBoxMesh(part, color) {
94        let geometry = new THREE.BoxGeometry(2, 2, 2);
95        geometry.scale(
96            part.get_scale().get_x(),
97            part.get_scale().get_y(),
98            part.get_scale().get_z());
99
100        let material = this.transformations.getNewMaterial(color);
101        let mesh = new THREE.Mesh(geometry, material);
102        mesh.position.set(
103            part.get_p().get_x(),
104            part.get_p().get_y(),
105            part.get_p().get_z());
106
107        let angles = part.get_o().getAngles();
108        mesh.rotation.copy(this.transformations.getPartRotation(
109            angles.get_x(),
110            angles.get_y(),
111            angles.get_z()));
112
113        mesh.userData = {
114            isBodyElement: true,
115            type: 'p',
116            data: part,
117            mesh: mesh,
118            isPhysical: this.physics,
119            connectedJoints: []
120        };
121        return mesh;
122    }
123
124    /**
125     * Creates cylinder mesh for a given part
126     * @param {Module.Part} part part, for which Mesh is generated
127     * @returns {PartMesh} info about part mesh
128     */
129    getNewCylinderMesh(part, color) {
130        let geometry = new THREE.CylinderGeometry(1, 1, 2, 32);
131        let material = this.transformations.getNewMaterial(color);
132
133        geometry.scale(
134            part.get_scale().get_y(),
135            part.get_scale().get_x(),
136            part.get_scale().get_z());
137
138        let mesh = null;
139        if (part.get_scale().get_y() == part.get_scale().get_z()) {
140            mesh = new THREE.Mesh(geometry, material);
141        } else {
142            mesh = new THREE.Mesh(geometry, material);
143        }
144        mesh.position.set(
145            part.get_p().get_x(),
146            part.get_p().get_y(),
147            part.get_p().get_z());
148
149        let angles = part.get_o().getAngles();
150        let m = this.transformations.getCylinderPartRotationMatrix(
151            angles.get_x(),
152            angles.get_y(),
153            angles.get_z());
154
155        mesh.rotation.setFromRotationMatrix(m);
156
157        mesh.userData = {
158            isBodyElement: true,
159            type: 'p',
160            data: part,
161            mesh: mesh,
162            isPhysical: this.physics,
163            connectedJoints: []
164        };
165        return mesh;
166    }
167
168    /**
169     * Creates part mesh according to which shape should be applied for a given
170     * part.
171     * @param {Module.Part} part part, for which Mesh is generated
172     * @returns {PartMesh} info about part mesh
173     */
174    create(part, color) {
175
176        let shape = part.get_shape();
177        if (this.partShapes['SHAPE_ELLIPSOID'].value == shape) {
178            return this.getNewSphereMesh(
179                part,
180                color,
181                this.config.ellipsoidShape.radius,
182                this.config.ellipsoidShape.segments, true);
183        }
184        else if (this.partShapes['SHAPE_CUBOID'].value == shape) {
185            return this.getNewBoxMesh(part, color);
186        }
187        else if (this.partShapes['SHAPE_CYLINDER'].value == shape) {
188            return this.getNewCylinderMesh(part, color);
189        }
190        return this.getNewSphereMesh(
191            part,
192            color,
193            this.config.defaultShape.radius,
194            this.config.defaultShape.segments,
195            false);
196    }
197}
198
199export default PartMeshFactory;
Note: See TracBrowser for help on using the repository browser.