Compare commits
1 Commits
Author | SHA1 | Date | |
---|---|---|---|
4b0dae9236 |
Binary file not shown.
@ -4,14 +4,13 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Benedek László - IH1RZJ - masodik beadandó: Lego Batman</title>
|
||||
<title>Benedek László - IH1RZJ - első beadandó: Lego Batman</title>
|
||||
<script async src="./dist/es-module-shims.js"></script>
|
||||
<script type="importmap">
|
||||
{
|
||||
"imports": {
|
||||
"three": "./js-r167/build/three.module.min.js",
|
||||
"TrackballControls": "./js-r167/examples/jsm/controls/TrackballControls.js",
|
||||
"OBJLoader": "./js-r167/examples/jsm/loaders/OBJLoader.js"
|
||||
"TrackballControls": "./js-r167/examples/jsm/controls/TrackballControls.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -36,16 +35,11 @@
|
||||
<script type="module">
|
||||
import * as THREE from "three";
|
||||
import { TrackballControls } from "TrackballControls";
|
||||
import { OBJLoader } from "OBJLoader";
|
||||
|
||||
class SceneLoader {
|
||||
static FromJson(data) {
|
||||
let _scene = new THREE.Scene();
|
||||
|
||||
let geometries = {};
|
||||
let materials = {};
|
||||
let objects = {};
|
||||
|
||||
const geometryTypes = {
|
||||
"CircleGeometry": THREE.CircleGeometry,
|
||||
"PlaneGeometry": THREE.PlaneGeometry,
|
||||
@ -57,109 +51,54 @@
|
||||
};
|
||||
|
||||
const materialTypes = {
|
||||
"MeshBasicMaterial": THREE.MeshBasicMaterial,
|
||||
"MeshLambertMaterial": THREE.MeshLambertMaterial,
|
||||
"MeshPhongMaterial": THREE.MeshPhongMaterial,
|
||||
"MeshStandardMaterial": THREE.MeshStandardMaterial
|
||||
"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);
|
||||
if (value.texture) {
|
||||
materials[key].map = new THREE.TextureLoader().load(value.texture.path);
|
||||
if (value.texture.repeat == true) {
|
||||
materials[key].map.wrapS = THREE.RepeatWrapping;
|
||||
materials[key].map.wrapT = THREE.RepeatWrapping;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function createObject(data, name) {
|
||||
const objectConstructors = {
|
||||
"empty": data => new THREE.Object3D(),
|
||||
"OBJ": data => {
|
||||
let empty = new THREE.Object3D();
|
||||
let loader = new OBJLoader();
|
||||
loader.load(
|
||||
data.url,
|
||||
result => {
|
||||
result.traverse(element => {
|
||||
if (element instanceof THREE.Mesh) {
|
||||
element.material = materials[data.material];
|
||||
if (data.castShadow) element.castShadow = data.castShadow;
|
||||
if (data.receiveShadow) element.receiveShadow = data.receiveShadow;
|
||||
empty.add(element);
|
||||
}
|
||||
})
|
||||
});
|
||||
return empty;
|
||||
},
|
||||
"Mesh": data => new THREE.Mesh(geometries[data.geometry], materials[data.material]),
|
||||
"LineSegments": data => new THREE.LineSegments(geometries[data.geometry], materials[data.material]),
|
||||
|
||||
"AmbientLight": data => new THREE.AmbientLight(data.color ? data.color : 0xffffff, data.intensity ? data.intensity : 1),
|
||||
"PointLight": data => {
|
||||
let object = new THREE.PointLight(data.color ? data.color : 0xffffff, data.intensity ? data.intensity : 1);
|
||||
object.distance = data.distance ? data.distance : 100;
|
||||
return object;
|
||||
},
|
||||
"SpotLight": data => {
|
||||
let object = new THREE.SpotLight(data.color ? data.color : 0xffffff, data.intensity ? data.intensity : 1);
|
||||
object.angle = THREE.MathUtils.degToRad(data.angle ? data.angle : 45);
|
||||
if (data.position) object.position.set(...data.position);
|
||||
object.target = objects[data.target];
|
||||
object.distance = data.distance ? data.distance : 100;
|
||||
return object;
|
||||
},
|
||||
"DirectionalLight": data => {
|
||||
let object = new THREE.DirectionalLight(data.color ? data.color : 0xffffff, data.intensity ? data.intensity : 1);
|
||||
if (data.position) object.position.set(...data.position);
|
||||
object.target = objects[data.target];
|
||||
object.distance = data.distance ? data.distance : 100;
|
||||
object.shadow.camera.left = -50;
|
||||
object.shadow.camera.right = 50;
|
||||
object.shadow.camera.bottom = -50;
|
||||
object.shadow.camera.top = 50;
|
||||
return object;
|
||||
},
|
||||
"HemisphereLight": data => new THREE.HemisphereLight(data.color ? data.color : 0xffffff, data.groundColor ? data.groundColor : 0x00ff00, data.intensity ? data.intensity : 1),
|
||||
|
||||
"PointLightHelper": data => new THREE.PointLightHelper(objects[data.target], data.sphereSize ? data.sphereSize : 5),
|
||||
"SpotLightHelper": data => new THREE.SpotLightHelper(objects[data.target]),
|
||||
"DirectionalLightHelper": data => new THREE.DirectionalLightHelper(objects[data.target], data.planeSize ? data.planeSize : 10),
|
||||
"HemisphereLightHelper": data => new THREE.HemisphereLightHelper(objects[data.target], data.sphereSize ? data.sphereSize : 5),
|
||||
"AxesHelper": data => new THREE.AxesHelper(data.helperSize ? data.helperSize : 10),
|
||||
"ArrowHelper": data => new THREE.ArrowHelper(...(data.direction ? data.direction : [1, 0, 0]), ...(data.origin ? data.origin : [0, 0, 0]), data.length ? data.length : 10, data.color ? data.color : 0xff00ff),
|
||||
"ShadowCameraHelper": data => new THREE.CameraHelper(objects[data.target].shadow.camera),
|
||||
};
|
||||
|
||||
// create object
|
||||
function createMesh(data) {
|
||||
let mesh;
|
||||
let type = data.type ? data.type : "Mesh";
|
||||
let object = (objects[name] = objectConstructors[type](data));
|
||||
|
||||
if (data.position) object.position.set(...data.position);
|
||||
if (data.rotation) object.rotation.set(...Array.from(data.rotation, x => THREE.MathUtils.degToRad(x)));
|
||||
if (data.scale) object.scale.set(...data.scale);
|
||||
if (data.castShadow) object.castShadow = data.castShadow;
|
||||
if (data.receiveShadow) object.receiveShadow = data.receiveShadow;
|
||||
if (data.animation) object.animation = data.animation;
|
||||
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);
|
||||
|
||||
// add children to parent
|
||||
if (data.children) {
|
||||
for (let [key, value] of Object.entries(data.children)) {
|
||||
object.add(createObject(value, key));
|
||||
mesh.add(createMesh(value));
|
||||
}
|
||||
}
|
||||
|
||||
return object;
|
||||
return mesh;
|
||||
}
|
||||
|
||||
for (let [key, value] of Object.entries(data.objects)) {
|
||||
_scene.add(createObject(value, key));
|
||||
for (let [key, value] of Object.entries(data.meshes)) {
|
||||
_scene.add(meshes[key] = createMesh(value));
|
||||
}
|
||||
|
||||
return _scene;
|
||||
@ -167,23 +106,20 @@
|
||||
};
|
||||
|
||||
const fov = 75;
|
||||
const near = 0.1;
|
||||
const far = 10000;
|
||||
const near = 0.01;
|
||||
const far = 1000;
|
||||
const rotateSpeed = 5.0;
|
||||
const panSpeed = 1.0;
|
||||
|
||||
const loop = true;
|
||||
let canvas, renderer, scene, camera, controls;
|
||||
|
||||
let canvas, renderer, scene, camera, controls, clock;
|
||||
|
||||
init().then(loop && animate());
|
||||
init().then(animate());
|
||||
|
||||
async function init() {
|
||||
canvas = document.querySelector("#canvas");
|
||||
renderer = new THREE.WebGLRenderer({ antialias: true, canvas: canvas, alpha: true });
|
||||
renderer.shadowMap.enabled = true;
|
||||
renderer.setSize(window.innerWidth, window.innerHeight);
|
||||
renderer.setClearColor("black");
|
||||
renderer.setClearColor(0xadadad);
|
||||
|
||||
camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, near, far);
|
||||
camera.position.set(0, 10, 50);
|
||||
@ -192,16 +128,12 @@
|
||||
controls.rotateSpeed = rotateSpeed;
|
||||
controls.panSpeed = panSpeed;
|
||||
|
||||
clock = new THREE.Clock();
|
||||
|
||||
scene = await fetch("scene.json")
|
||||
.then((response) => response.json())
|
||||
.catch(reason => console.log(`fetch failed: ${reason}`))
|
||||
.then((json) => SceneLoader.FromJson(json));
|
||||
|
||||
window.addEventListener("resize", handleWindowResize, false);
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
function handleWindowResize() {
|
||||
@ -217,19 +149,6 @@
|
||||
function animate() {
|
||||
requestAnimationFrame(animate);
|
||||
controls.update();
|
||||
|
||||
let delta = clock.getDelta();
|
||||
let time = clock.getElapsedTime();
|
||||
|
||||
scene.traverse((element)=>{
|
||||
if (element.animation) {
|
||||
(() => {
|
||||
eval(element.animation);
|
||||
})
|
||||
.call({ element: element, delta: delta, time: time });
|
||||
}
|
||||
})
|
||||
|
||||
render();
|
||||
}
|
||||
|
||||
|
@ -1,57 +0,0 @@
|
||||
# Blender modellezési lépések
|
||||
|
||||
1. Default Cube kitörlése
|
||||
2. Referenciaképek importálása
|
||||
3. Láb modellje
|
||||
- új cube mesh
|
||||
- referenciához igazítom (move, scale)
|
||||
- loopcut, extrude -> láb fuggőleges része
|
||||
- új cylinder mesh -> láb teteje
|
||||
- cylinder aljának törlése
|
||||
- cylinder és a láb többi részének összekötése új face-ek létrehozásával
|
||||
- origin áthelyezése
|
||||
- modell duplikálása és tükrözése -> másik láb
|
||||
4. Test modellje
|
||||
- új cube mesh, de csak a test egyik oldalához
|
||||
- referenciához igazítás
|
||||
- mirror modifier
|
||||
- felső lap scale
|
||||
- élek lekerekítése
|
||||
5. Kar modellje
|
||||
- új uv sphere mesh
|
||||
- aljának törlése
|
||||
- alsó körív extrude, könyöknél újabb extrude és forgatás
|
||||
- könyöknél lekerekítés
|
||||
- henger végének lezárása új face-el
|
||||
- duplikálás és tükrözés
|
||||
6. Kéz modellje
|
||||
- új cylinder mesh
|
||||
- scale, rotate, move
|
||||
- új cylinder a maroknak
|
||||
- inset
|
||||
- duplikálás és tükrözés
|
||||
7. Fej modellje
|
||||
- új cylinder mesh
|
||||
- extrude és scale a referencia követésével
|
||||
- lekerekítés
|
||||
8. Sisak modellje
|
||||
- új sphere mesh
|
||||
- félbevágom és tükrözöm modifierrel
|
||||
- scale
|
||||
- proportional editing referencia alapján
|
||||
- extrude az orrnál
|
||||
- knife tool -> szem kivágása
|
||||
- szem inset és extrude
|
||||
- száj kivágása knide toollal
|
||||
- subdivision surface
|
||||
9. Köpeny modellje
|
||||
- új plain mesh
|
||||
- knife tool -> referencia körbevágása
|
||||
- remesh, solidify, subdivision modifier
|
||||
- pinning vertex group a nyak körül
|
||||
- collision a testre
|
||||
- cloth simulation
|
||||
10. Fények hozzáadása
|
||||
11. Materialok beállítása
|
||||
12. Kamera beállítása
|
||||
13. Póz beállítása
|
3801
batman.obj
3801
batman.obj
File diff suppressed because it is too large
Load Diff
947
scene.json
947
scene.json
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Before Width: | Height: | Size: 2.0 MiB |
BIN
textures/mud.jpg
BIN
textures/mud.jpg
Binary file not shown.
Before Width: | Height: | Size: 28 KiB |
Loading…
Reference in New Issue
Block a user