source: js/human_3d_alignment/src/visualization/partmeshfactory.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: 6.8 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, sphereRadius, segments, applyScale) {
39        let geometry = new THREE.SphereGeometry(sphereRadius, segments, segments);
40        let material = this.transformations.getNewMaterial(
41            part.get_vcolor().get_x(),
42            part.get_vcolor().get_y(),
43            part.get_vcolor().get_z());
44        let mesh = null;
45        if (applyScale) {
46            geometry.scale(
47                part.get_scale().get_x(),
48                part.get_scale().get_y(),
49                part.get_scale().get_z());
50            if (part.get_scale().get_x() == part.get_scale().get_y() &&
51                part.get_scale().get_x() == part.get_scale().get_z()) {
52                mesh = new THREE.Mesh(geometry, material);
53            } else {
54                mesh = new THREE.Mesh(geometry, material);
55            }
56        }
57        else {
58            mesh = new THREE.Mesh(geometry, material);
59        }
60        mesh.position.set(
61            part.get_p().get_x(),
62            part.get_p().get_y(),
63            part.get_p().get_z());
64
65        // if (applyScale) {
66        //     mesh.scale.set(
67        //         part.get_scale().get_x(),
68        //         part.get_scale().get_y(),
69        //         part.get_scale().get_z());
70        // }
71
72        let angles = part.get_o().getAngles();
73        mesh.rotation.copy(
74            this.transformations.getPartRotation(
75                angles.get_x(),
76                angles.get_y(),
77                angles.get_z())
78        );
79
80        mesh.userData = {
81            isBodyElement: true,
82            type: 'p',
83            data: part,
84            mesh: mesh,
85            isPhysical: this.physics,
86            connectedJoints: []
87        };
88        return mesh;
89    }
90
91    /**
92     * Creates box mesh for a given part
93     * @param {Module.Part} part part, for which Mesh is generated
94     * @returns {PartMesh} info about part mesh
95     */
96    getNewBoxMesh(part) {
97        let geometry = new THREE.BoxGeometry(2, 2, 2);
98        geometry.scale(
99            part.get_scale().get_x(),
100            part.get_scale().get_y(),
101            part.get_scale().get_z());
102
103        let material = this.transformations.getNewMaterial(
104            part.get_vcolor().get_x(),
105            part.get_vcolor().get_y(),
106            part.get_vcolor().get_z());
107        let mesh = new THREE.Mesh(geometry, material);
108        mesh.position.set(
109            part.get_p().get_x(),
110            part.get_p().get_y(),
111            part.get_p().get_z());
112
113        let angles = part.get_o().getAngles();
114        mesh.rotation.copy(this.transformations.getPartRotation(
115            angles.get_x(),
116            angles.get_y(),
117            angles.get_z()));
118
119        mesh.userData = {
120            isBodyElement: true,
121            type: 'p',
122            data: part,
123            mesh: mesh,
124            isPhysical: this.physics,
125            connectedJoints: []
126        };
127        return mesh;
128    }
129
130    /**
131     * Creates cylinder mesh for a given part
132     * @param {Module.Part} part part, for which Mesh is generated
133     * @returns {PartMesh} info about part mesh
134     */
135    getNewCylinderMesh(part) {
136        let geometry = new THREE.CylinderGeometry(1, 1, 2, 32);
137        let material = this.transformations.getNewMaterial(
138            part.get_vcolor().get_x(),
139            part.get_vcolor().get_y(),
140            part.get_vcolor().get_z());
141
142        geometry.scale(
143            part.get_scale().get_y(),
144            part.get_scale().get_x(),
145            part.get_scale().get_z());
146
147        let mesh = null;
148        if (part.get_scale().get_y() == part.get_scale().get_z()) {
149            mesh = new THREE.Mesh(geometry, material);
150        } else {
151            mesh = new THREE.Mesh(geometry, material);
152        }
153        mesh.position.set(
154            part.get_p().get_x(),
155            part.get_p().get_y(),
156            part.get_p().get_z());
157
158        let angles = part.get_o().getAngles();
159        let m = this.transformations.getCylinderPartRotationMatrix(
160            angles.get_x(),
161            angles.get_y(),
162            angles.get_z());
163
164        mesh.rotation.setFromRotationMatrix(m);
165
166        mesh.userData = {
167            isBodyElement: true,
168            type: 'p',
169            data: part,
170            mesh: mesh,
171            isPhysical: this.physics,
172            connectedJoints: []
173        };
174        return mesh;
175    }
176
177    /**
178     * Creates part mesh according to which shape should be applied for a given
179     * part.
180     * @param {Module.Part} part part, for which Mesh is generated
181     * @returns {PartMesh} info about part mesh
182     */
183    create(part) {
184
185        let shape = part.get_shape();
186        if (this.partShapes['SHAPE_ELLIPSOID'].value == shape) {
187            return this.getNewSphereMesh(
188                part,
189                this.config.ellipsoidShape.radius,
190                this.config.ellipsoidShape.segments, true);
191        }
192        else if (this.partShapes['SHAPE_CUBOID'].value == shape) {
193            return this.getNewBoxMesh(part);
194        }
195        else if (this.partShapes['SHAPE_CYLINDER'].value == shape) {
196            return this.getNewCylinderMesh(part);
197        }
198        return this.getNewSphereMesh(
199            part,
200            this.config.defaultShape.radius,
201            this.config.defaultShape.segments,
202            false);
203    }
204}
205
206export default PartMeshFactory;
Note: See TracBrowser for help on using the repository browser.