Compare commits
5 Commits
Author | SHA1 | Date | |
---|---|---|---|
4d5ef5fa63 | |||
010cf6534b | |||
14a988baa5 | |||
d90c41565e | |||
fdf2adf3c9 |
BIN
BenedekLaszlo_IH1RZJ.blend
Normal file
BIN
BenedekLaszlo_IH1RZJ.blend
Normal file
Binary file not shown.
@ -4,13 +4,14 @@
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||
<title>Benedek László - IH1RZJ - első beadandó: Lego Batman</title>
|
||||
<title>Benedek László - IH1RZJ - masodik 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"
|
||||
"TrackballControls": "./js-r167/examples/jsm/controls/TrackballControls.js",
|
||||
"OBJLoader": "./js-r167/examples/jsm/loaders/OBJLoader.js"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@ -35,11 +36,16 @@
|
||||
<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,
|
||||
@ -51,54 +57,109 @@
|
||||
};
|
||||
|
||||
const materialTypes = {
|
||||
"MeshBasicMaterial": THREE.MeshBasicMaterial
|
||||
"MeshBasicMaterial": THREE.MeshBasicMaterial,
|
||||
"MeshLambertMaterial": THREE.MeshLambertMaterial,
|
||||
"MeshPhongMaterial": THREE.MeshPhongMaterial,
|
||||
"MeshStandardMaterial": THREE.MeshStandardMaterial
|
||||
};
|
||||
|
||||
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 createMesh(data) {
|
||||
let mesh;
|
||||
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
|
||||
let type = data.type ? data.type : "Mesh";
|
||||
let object = (objects[name] = objectConstructors[type](data));
|
||||
|
||||
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.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;
|
||||
|
||||
// add children to parent
|
||||
if (data.children) {
|
||||
for (let [key, value] of Object.entries(data.children)) {
|
||||
mesh.add(createMesh(value));
|
||||
object.add(createObject(value, key));
|
||||
}
|
||||
}
|
||||
|
||||
return mesh;
|
||||
return object;
|
||||
}
|
||||
|
||||
for (let [key, value] of Object.entries(data.meshes)) {
|
||||
_scene.add(meshes[key] = createMesh(value));
|
||||
for (let [key, value] of Object.entries(data.objects)) {
|
||||
_scene.add(createObject(value, key));
|
||||
}
|
||||
|
||||
return _scene;
|
||||
@ -106,20 +167,23 @@
|
||||
};
|
||||
|
||||
const fov = 75;
|
||||
const near = 0.01;
|
||||
const far = 1000;
|
||||
const near = 0.1;
|
||||
const far = 10000;
|
||||
const rotateSpeed = 5.0;
|
||||
const panSpeed = 1.0;
|
||||
|
||||
let canvas, renderer, scene, camera, controls;
|
||||
const loop = true;
|
||||
|
||||
init().then(animate());
|
||||
let canvas, renderer, scene, camera, controls, clock;
|
||||
|
||||
init().then(loop && 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(0xadadad);
|
||||
renderer.setClearColor("black");
|
||||
|
||||
camera = new THREE.PerspectiveCamera(fov, window.innerWidth / window.innerHeight, near, far);
|
||||
camera.position.set(0, 10, 50);
|
||||
@ -128,12 +192,16 @@
|
||||
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() {
|
||||
@ -149,6 +217,19 @@
|
||||
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();
|
||||
}
|
||||
|
||||
|
57
BenedekLaszlo_IH1RZJ.txt
Normal file
57
BenedekLaszlo_IH1RZJ.txt
Normal file
@ -0,0 +1,57 @@
|
||||
# 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
Normal file
3801
batman.obj
Normal file
File diff suppressed because it is too large
Load Diff
1119
scene.json
1119
scene.json
File diff suppressed because it is too large
Load Diff
BIN
textures/moon.jpg
Normal file
BIN
textures/moon.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.0 MiB |
BIN
textures/mud.jpg
Normal file
BIN
textures/mud.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in New Issue
Block a user