This commit is contained in:
BENEDEK László 2024-09-30 11:51:39 +02:00
parent 7699587ab1
commit 5772f94a12
2 changed files with 283 additions and 338 deletions

View File

@ -36,43 +36,104 @@
import * as THREE from "three"; import * as THREE from "three";
import { TrackballControls } from "TrackballControls"; import { TrackballControls } from "TrackballControls";
let fov = 75; class SceneLoader {
let near = 0.01; static FromJson(data) {
let far = 1000; let _scene = new THREE.Scene();
let rotateSpeed = 5.0;
let panSpeed = 1.0; const geometryTypes = {
"CircleGeometry": THREE.CircleGeometry,
"PlaneGeometry": THREE.PlaneGeometry,
"BoxGeometry": THREE.BoxGeometry,
"SphereGeometry": THREE.SphereGeometry,
"ConeGeometry": THREE.ConeGeometry,
"CylinderGeometry": THREE.CylinderGeometry,
"TorusGeometry": THREE.TorusGeometry,
};
const materialTypes = {
"MeshBasicMaterial": THREE.MeshBasicMaterial
};
let geometries = {};
let materials = {};
let meshes = {};
for (let [key, value] of Object.entries(data.geometries)) {
geometries[key] = new geometryTypes[value.type](...value.options);
}
for (let [key, value] of Object.entries(data.materials)) {
materials[key] = new materialTypes[value.type](value.options);
}
function createMesh(data) {
let mesh;
let type = data.type ? data.type : "Mesh";
switch (type) {
case "empty":
mesh = new THREE.Object3D();
break;
case "Mesh":
mesh = new THREE.Mesh(geometries[data.geometry], materials[data.material]);
break;
case "LineSegments":
mesh = new THREE.LineSegments(geometries[data.geometry], materials[data.material]);
break;
default:
throw "unknown mesh type";
}
if (data.position) mesh.position.set(...data.position);
if (data.rotation) mesh.rotation.set(...Array.from(data.rotation, x => THREE.MathUtils.degToRad(x)));
if (data.scale) mesh.scale.set(...data.scale);
if (data.children) {
for (let [key, value] of Object.entries(data.children)) {
mesh.add(createMesh(value));
}
}
return mesh;
}
for (let [key, value] of Object.entries(data.meshes)) {
_scene.add(meshes[key] = createMesh(value));
}
return _scene;
}
};
const fov = 75;
const near = 0.01;
const far = 1000;
const rotateSpeed = 5.0;
const panSpeed = 1.0;
let canvas, renderer, scene, camera, controls; let canvas, renderer, scene, camera, controls;
init(); init().then(animate());
animate();
function init() { async function init() {
canvas = document.querySelector("#canvas"); canvas = document.querySelector("#canvas");
renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvas }); renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvas, alpha: true });
renderer.setSize(window.innerWidth, window.innerHeight); renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setClearColor(0xadadad);
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, near, far); camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, near, far);
camera.position.z = 15; camera.position.set(0, 10, 50);
controls = new TrackballControls(camera, canvas); controls = new TrackballControls(camera, canvas);
controls.rotateSpeed = rotateSpeed; controls.rotateSpeed = rotateSpeed;
controls.panSpeed = panSpeed; controls.panSpeed = panSpeed;
scene.add(new THREE.AxesHelper(5)); scene = await fetch("scene.json")
loadScene();
window.addEventListener("resize", handleWindowResize, false);
}
function loadScene() {
fetch("scene.json")
.then((response) => response.json()) .then((response) => response.json())
.catch(reason => console.log(`fetch failed: ${reason}`)) .catch(reason => console.log(`fetch failed: ${reason}`))
.then((json) => SceneLoader.FromJson(json, scene)); .then((json) => SceneLoader.FromJson(json));
window.addEventListener("resize", handleWindowResize, false);
} }
function handleWindowResize() { function handleWindowResize() {
@ -94,61 +155,6 @@
function render() { function render() {
renderer.render(scene, camera); renderer.render(scene, camera);
} }
class SceneLoader {
static FromJson(data, scene, camera) {
let geometryTypes = {
"CircleGeometry": THREE.CircleGeometry,
"PlaneGeometry": THREE.PlaneGeometry,
"BoxGeometry": THREE.BoxGeometry,
"SphereGeometry": THREE.SphereGeometry,
"ConeGeometry": THREE.ConeGeometry,
"CylinderGeometry": THREE.CylinderGeometry,
"TorusGeometry": THREE.TorusGeometry,
};
let materialTypes = {
"MeshBasicMaterial": THREE.MeshBasicMaterial
};
let geometries = {};
let materials = {};
let meshes = {};
for (let [key, value] of Object.entries(data.geometries)) {
geometries[key] = new geometryTypes[value.type](...value.options);
}
for (let [key, value] of Object.entries(data.materials)) {
materials[key] = new materialTypes[value.type](value.options);
}
function createMesh(data) {
let mesh;
if (data.type === "empty") {
mesh = new THREE.Object3D();
} else {
mesh = new THREE.Mesh(geometries[data.geometry], materials[data.material]);
}
mesh.position.set(...data.position);
mesh.rotation.set(...Array.from(data.rotation, x => THREE.MathUtils.degToRad(x)));
mesh.scale.set(...data.scale);
if (data.children) {
for (let [key, value] of Object.entries(data.children)) {
mesh.add(createMesh(value));
}
}
return mesh;
}
for (let [key, value] of Object.entries(data.meshes)) {
scene.add(meshes[key] = createMesh(value));
}
}
};
</script> </script>
</body> </body>

View File

@ -97,37 +97,48 @@
} }
}, },
"materials": { "materials": {
"purple": { "purple_frame": {
"type": "MeshBasicMaterial", "type": "MeshBasicMaterial",
"options": { "options": {
"color": "rgb(255, 0, 255)", "color": "rgb(255, 0, 255)",
"wireframe": true "wireframe": true
} }
},
"black": {
"type": "MeshBasicMaterial",
"options": {
"color": "rgb(0, 0, 0)",
"wireframe": false
}
},
"white_frame": {
"type": "MeshBasicMaterial",
"options": {
"color": "rgb(255, 255, 255)",
"wireframe": true
}
},
"skin": {
"type": "MeshBasicMaterial",
"options": {
"color": "rgb(246, 215, 179)",
"wireframe": false
}
} }
}, },
"meshes": { "meshes": {
"hip": { "hip": {
"geometry": "hip", "geometry": "hip",
"material": "purple", "material": "black",
"position": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"hip_wireframe": {
"type": "LineSegments",
"geometry": "hip",
"material": "white_frame"
},
"r_thigh": { "r_thigh": {
"geometry": "thigh", "geometry": "thigh",
"material": "purple", "material": "black",
"position": [ "position": [
-3.57, -3.57,
-3, -3,
@ -144,9 +155,14 @@
1 1
], ],
"children": { "children": {
"r_thigh_wireframe": {
"type": "LineSegments",
"geometry": "thigh",
"material": "white_frame"
},
"r_leg": { "r_leg": {
"geometry": "leg", "geometry": "leg",
"material": "purple", "material": "black",
"position": [ "position": [
-4.15, -4.15,
0, 0,
@ -157,30 +173,27 @@
0, 0,
-90 -90
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_leg_wireframe": {
"type": "LineSegments",
"geometry": "leg",
"material": "white_frame"
},
"r_feet": { "r_feet": {
"geometry": "feet", "geometry": "feet",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-5.75, -5.75,
1.125 1.125
], ],
"rotation": [ "children": {
0, "r_feet_wireframe": {
0, "type": "LineSegments",
0 "geometry": "feet",
], "material": "white_frame"
"scale": [ }
1, }
1,
1
]
} }
} }
} }
@ -188,7 +201,7 @@
}, },
"l_thigh": { "l_thigh": {
"geometry": "thigh", "geometry": "thigh",
"material": "purple", "material": "black",
"position": [ "position": [
3.57, 3.57,
-3, -3,
@ -205,9 +218,14 @@
1 1
], ],
"children": { "children": {
"l_thigh_wireframe": {
"type": "LineSegments",
"geometry": "thigh",
"material": "white_frame"
},
"l_leg": { "l_leg": {
"geometry": "leg", "geometry": "leg",
"material": "purple", "material": "black",
"position": [ "position": [
-4.15, -4.15,
0, 0,
@ -218,30 +236,27 @@
0, 0,
-90 -90
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_leg_wireframe": {
"type": "LineSegments",
"geometry": "leg",
"material": "white_frame"
},
"l_feet": { "l_feet": {
"geometry": "feet", "geometry": "feet",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-5.75, -5.75,
1.125 1.125
], ],
"rotation": [ "children": {
0, "l_feet_wireframe": {
0, "type": "LineSegments",
0 "geometry": "feet",
], "material": "white_frame"
"scale": [ }
1, }
1,
1
]
} }
} }
} }
@ -249,25 +264,10 @@
}, },
"spine": { "spine": {
"type": "empty", "type": "empty",
"position": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_shoulder": { "r_shoulder": {
"geometry": "arm_joint", "geometry": "arm_joint",
"material": "purple", "material": "black",
"position": [ "position": [
-6.8, -6.8,
9.5, 9.5,
@ -278,34 +278,29 @@
0, 0,
-20 -20
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_shoulder_wireframe": {
"type": "LineSegments",
"geometry": "arm_joint",
"material": "white_frame"
},
"r_upper_arm": { "r_upper_arm": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_upper_arm_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
},
"r_elbow": { "r_elbow": {
"geometry": "arm_joint", "geometry": "arm_joint",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
@ -316,31 +311,26 @@
0, 0,
0 0
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_elbow_wireframe": {
"type": "LineSegments",
"geometry": "arm_joint",
"material": "white_frame"
},
"r_lower_arm": { "r_lower_arm": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_lower_arm_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
},
"r_wrist_helper": { "r_wrist_helper": {
"type": "empty", "type": "empty",
"position": [ "position": [
@ -348,20 +338,10 @@
-3, -3,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"r_hand": { "r_hand": {
"geometry": "hand", "geometry": "hand",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.4, -2.4,
@ -376,27 +356,30 @@
1, 1,
1, 1,
9 9
] ],
"children": {
"r_hand_wireframe": {
"type": "LineSegments",
"geometry": "hand",
"material": "white_frame"
}
}
}, },
"r_wrist": { "r_wrist": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": [ "scale": [
0.5, 0.5,
0.25, 0.25,
0.5 0.5
], ],
"children": {} "children": {
"r_wrist_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
}
}
} }
} }
} }
@ -410,7 +393,7 @@
}, },
"l_shoulder": { "l_shoulder": {
"geometry": "arm_joint", "geometry": "arm_joint",
"material": "purple", "material": "black",
"position": [ "position": [
6.8, 6.8,
9.5, 9.5,
@ -421,34 +404,29 @@
0, 0,
20 20
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_shoudler_wireframe": {
"type": "LineSegments",
"geometry": "arm_joint",
"material": "white_frame"
},
"l_upper_arm": { "l_upper_arm": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_upper_arm_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
},
"l_elbow": { "l_elbow": {
"geometry": "arm_joint", "geometry": "arm_joint",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
@ -459,31 +437,26 @@
0, 0,
0 0
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_elbow_wireframe": {
"type": "LineSegments",
"geometry": "arm_joint",
"material": "white_frame"
},
"l_lower_arm": { "l_lower_arm": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.75, -2.75,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_lower_arm_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
},
"r_wrist_helper": { "r_wrist_helper": {
"type": "empty", "type": "empty",
"position": [ "position": [
@ -491,20 +464,10 @@
-3, -3,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"l_hand": { "l_hand": {
"geometry": "hand", "geometry": "hand",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
-2.4, -2.4,
@ -519,27 +482,30 @@
1, 1,
1, 1,
9 9
] ],
"children": {
"l_hand_wireframe": {
"type": "LineSegments",
"geometry": "hand",
"material": "white_frame"
}
}
}, },
"l_wrist": { "l_wrist": {
"geometry": "arm", "geometry": "arm",
"material": "purple", "material": "black",
"position": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": [ "scale": [
0.5, 0.5,
0.25, 0.25,
0.5 0.5
], ],
"children": {} "children": {
"l_wrist_wireframe": {
"type": "LineSegments",
"geometry": "arm",
"material": "white_frame"
}
}
} }
} }
} }
@ -553,45 +519,32 @@
}, },
"neck": { "neck": {
"geometry": "neck", "geometry": "neck",
"material": "purple", "material": "skin",
"position": [ "position": [
0, 0,
19.05, 19.05,
0 0
], ],
"rotation": [
0,
0,
0
],
"scale": [
1,
1,
1
],
"children": { "children": {
"neck_wireframe": {
"type": "LineSegments",
"geometry": "neck",
"material": "white_frame"
},
"head": { "head": {
"geometry": "head", "geometry": "head",
"material": "purple", "material": "skin",
"position": [ "children": {
0, "head_wireframe": {
0, "type": "LineSegments",
0 "geometry": "head",
], "material": "white_frame"
"rotation": [ }
0, }
0,
0
],
"scale": [
1,
1,
1
]
}, },
"chin": { "chin": {
"geometry": "head_border", "geometry": "head_border",
"material": "purple", "material": "skin",
"position": [ "position": [
0, 0,
-3.5, -3.5,
@ -602,36 +555,33 @@
0, 0,
0 0
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"chin_wireframe": {
"type": "LineSegments",
"geometry": "head_border",
"material": "white_frame"
},
"head_cap_bottom": { "head_cap_bottom": {
"geometry": "head_cap", "geometry": "head_cap",
"material": "purple", "material": "skin",
"position": [ "position": [
0, 0,
0, 0,
1 1
], ],
"rotation": [ "children": {
0, "head_cap_bottom_wireframe": {
0, "type": "LineSegments",
0 "geometry": "head_cap",
], "material": "white_frame"
"scale": [ }
1, }
1,
1
]
} }
} }
}, },
"scalp": { "scalp": {
"geometry": "head_border", "geometry": "head_border",
"material": "purple", "material": "skin",
"position": [ "position": [
0, 0,
3.5, 3.5,
@ -642,30 +592,27 @@
0, 0,
0 0
], ],
"scale": [
1,
1,
1
],
"children": { "children": {
"scalp_wireframe": {
"type": "LineSegments",
"geometry": "head_border",
"material": "white_frame"
},
"head_cap_top": { "head_cap_top": {
"geometry": "head_cap", "geometry": "head_cap",
"material": "purple", "material": "skin",
"position": [ "position": [
0, 0,
0, 0,
-1 -1
], ],
"rotation": [ "children": {
0, "head_cap_top_wireframe": {
0, "type": "LineSegments",
0 "geometry": "head_cap",
], "material": "white_frame"
"scale": [ }
1, }
1,
1
]
} }
} }
} }
@ -673,16 +620,6 @@
}, },
"body_helper": { "body_helper": {
"type": "empty", "type": "empty",
"position": [
0,
0,
0
],
"rotation": [
0,
0,
0
],
"scale": [ "scale": [
1, 1,
1, 1,
@ -691,7 +628,7 @@
"children": { "children": {
"body": { "body": {
"geometry": "body", "geometry": "body",
"material": "purple", "material": "black",
"position": [ "position": [
0, 0,
7.15, 7.15,
@ -702,11 +639,13 @@
45, 45,
0 0
], ],
"scale": [ "children": {
1, "body_wireframe": {
1, "type": "LineSegments",
1 "geometry": "body",
] "material": "white_frame"
}
}
} }
} }
} }