@@ -1,4 +1,11 @@ | |||||
Рисователь | Renderer | Рисователь | Renderer | ||||
0.2.0 | |||||
https://git.opengamestudio.org/KH/PuCOBATEJlb-renderer | |||||
x /пуск|run.js | |||||
/пуск|run.череда | |||||
/three.js | |||||
/фишка.gltf | |||||
x /🎬.js | |||||
/🎬.череда | |||||
x /📖.js | |||||
x /🧸.js | |||||
/🧸.череда |
@@ -1,5 +0,0 @@ | |||||
ПриветИзШаблона = мир => | |||||
{ | |||||
console.log("Привет из шаблона!"); | |||||
console.log("Hello from the template!"); | |||||
}; |
@@ -1,2 +0,0 @@ | |||||
пуск | |||||
привет из шаблона |
@@ -0,0 +1,112 @@ | |||||
{ | |||||
"asset" : { | |||||
"generator" : "Khronos glTF Blender I/O v1.2.75", | |||||
"version" : "2.0" | |||||
}, | |||||
"scene" : 0, | |||||
"scenes" : [ | |||||
{ | |||||
"name" : "Scene", | |||||
"nodes" : [ | |||||
0 | |||||
] | |||||
} | |||||
], | |||||
"nodes" : [ | |||||
{ | |||||
"mesh" : 0, | |||||
"name" : "Cube" | |||||
} | |||||
], | |||||
"meshes" : [ | |||||
{ | |||||
"name" : "Cube", | |||||
"primitives" : [ | |||||
{ | |||||
"attributes" : { | |||||
"POSITION" : 0, | |||||
"NORMAL" : 1, | |||||
"TANGENT" : 2, | |||||
"TEXCOORD_0" : 3 | |||||
}, | |||||
"indices" : 4 | |||||
} | |||||
] | |||||
} | |||||
], | |||||
"accessors" : [ | |||||
{ | |||||
"bufferView" : 0, | |||||
"componentType" : 5126, | |||||
"count" : 32, | |||||
"max" : [ | |||||
0.699999988079071, | |||||
0.5, | |||||
1 | |||||
], | |||||
"min" : [ | |||||
-0.699999988079071, | |||||
0, | |||||
-1 | |||||
], | |||||
"type" : "VEC3" | |||||
}, | |||||
{ | |||||
"bufferView" : 1, | |||||
"componentType" : 5126, | |||||
"count" : 32, | |||||
"type" : "VEC3" | |||||
}, | |||||
{ | |||||
"bufferView" : 2, | |||||
"componentType" : 5126, | |||||
"count" : 32, | |||||
"type" : "VEC4" | |||||
}, | |||||
{ | |||||
"bufferView" : 3, | |||||
"componentType" : 5126, | |||||
"count" : 32, | |||||
"type" : "VEC2" | |||||
}, | |||||
{ | |||||
"bufferView" : 4, | |||||
"componentType" : 5123, | |||||
"count" : 36, | |||||
"type" : "SCALAR" | |||||
} | |||||
], | |||||
"bufferViews" : [ | |||||
{ | |||||
"buffer" : 0, | |||||
"byteLength" : 384, | |||||
"byteOffset" : 0 | |||||
}, | |||||
{ | |||||
"buffer" : 0, | |||||
"byteLength" : 384, | |||||
"byteOffset" : 384 | |||||
}, | |||||
{ | |||||
"buffer" : 0, | |||||
"byteLength" : 512, | |||||
"byteOffset" : 768 | |||||
}, | |||||
{ | |||||
"buffer" : 0, | |||||
"byteLength" : 256, | |||||
"byteOffset" : 1280 | |||||
}, | |||||
{ | |||||
"buffer" : 0, | |||||
"byteLength" : 72, | |||||
"byteOffset" : 1536 | |||||
} | |||||
], | |||||
"buffers" : [ | |||||
{ | |||||
"byteLength" : 1608, | |||||
"uri" : "data:application/octet-stream;base64,MzMzvwAAAD8AAIC/MzMzPwAAAD8AAIA/MzMzPwAAAD8AAIC/MzMzPwAAAD8AAIA/MzMzvwAAAAAAAIA/MzMzPwAAAAAAAIA/MzMzvwAAAD8AAIA/MzMzvwAAAAAAAIC/MzMzvwAAAAAAAIA/MzMzPwAAAAAAAIC/MzMzvwAAAAAAAIA/MzMzvwAAAAAAAIC/MzMzPwAAAD8AAIC/MzMzPwAAAAAAAIA/MzMzPwAAAAAAAIC/MzMzvwAAAD8AAIC/MzMzPwAAAAAAAIC/MzMzvwAAAAAAAIC/MzMzvwAAAD8AAIA/MzMzPwAAAD8AAIA/MzMzvwAAAD8AAIA/MzMzvwAAAAAAAIA/MzMzvwAAAD8AAIA/MzMzvwAAAD8AAIC/MzMzvwAAAAAAAIC/MzMzPwAAAAAAAIC/MzMzPwAAAAAAAIA/MzMzvwAAAAAAAIA/MzMzPwAAAD8AAIA/MzMzvwAAAD8AAIC/MzMzPwAAAD8AAIC/MzMzPwAAAAAAAIC/AAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAgD8AAACAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAACAPwAAAIAAAACAAACAPwAAAIAAAACAAACAPwAAAIAAAACAAAAAAAAAAIAAAIC/AAAAAAAAAIAAAIC/AAAAAAAAAIAAAIC/AAAAAAAAgD8AAAAAAAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AAAAAAAAAAAAAIA/AACAvwAAAAAAAACAAACAvwAAAAAAAACAAACAvwAAAAAAAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAAAAAAAAgL8AAACAAACAPwAAAAAAAACAAAAAAAAAAIAAAIC/AAAAAAAAAIAAAIC/AAAAAAAAAIAAAIC/AACAPwAAAAAAAACAAACAPwAAgD8AAAAAAAAAgAAAgD8AAIA/AAAAAAAAAIAAAIA/AACAP6a5ZzQAAACAAACAPwAAgD+muWc0AAAAgAAAgD8AAIA/prlnNAAAAIAAAIA/AAAAAAAAgD++T3O0AACAPwAAAAAAAIA/vk9ztAAAgD8AAAAAAACAP75Pc7QAAIA/AACAPwAAAACC8rqzAACAPwAAgD8AAAAAgvK6swAAgD8AAIA/AAAAAILyurMAAIA/AAAAAAAAgL+7T/O0AACAPwAAAAAAAIC/u0/ztAAAgD8AAAAAAACAv7tP87QAAIA/AACAP6i5Z7QAAACAAACAPwAAgD+ouWe0AAAAgAAAgD8AAIA/qLlntAAAAIAAAIA/AACAPwAAAAAAAACAAACAPwAAgD+nueczAAAAgAAAgD8AAIA/p7nnMwAAAIAAAIA/AACAP6e55zMAAACAAACAPwAAAAAAAIA/vk/zswAAgD8AAAAAAACAP75P87MAAIA/AAAAAAAAgD++T/OzAACAPwAAgD8AAAAAQKIFtAAAgD8AAIA/AAAAAECiBbQAAIA/AACAPwAAAABAogW0AACAPwAAAAAAAIC/u0/ztAAAgD8AAIA/p7nnswAAAIAAAIA/AACAP6e557MAAACAAACAPwAAgD+nueezAAAAgAAAgD/aygY+5kCvPvvw/z5ITV4//PD/PuZArz778P8+SE1eP9XKBj58+H8/+/D/Pn34fz/YygY+SE1eP0tm8DjmQK8+qVLwOEhNXj9++H8/ffh/P7eyIT9Wl/I+t7IhP334fz/88P8+5kCvPrKjIT9JTV4/sqMhP+hArz7aygY+5kCvPv7w/z4A1Vc+38oGPvjUVz7YygY+SE1eP/vw/z5ITV4/2MoGPkhNXj/VygY+fPh/P9jKBj5ITV4/2soGPuZArz5LZvA45kCvPn74fz99+H8/ffh/P1SX8j63siE/VpfyPvvw/z5ITV4/2soGPuZArz788P8+5kCvPv7w/z4A1Vc+AAABAAIAAwAEAAUABgAHAAgACQAKAAsADAANAA4ADwAQABEAAAASAAEAEwAUABUAFgAXABgAGQAaABsADAAcAA0AHQAeAB8A" | |||||
} | |||||
] | |||||
} |
@@ -0,0 +1,136 @@ | |||||
// // // // | |||||
ОтслеживатьНажатияВРисователе = мир => | |||||
{ | |||||
мир.отслеживатьНажатияВРисователе = true; | |||||
уведомитьОНажатии = (событие) => | |||||
{ | |||||
if (!мир.отслеживатьНажатияВРисователе) | |||||
{ | |||||
return; | |||||
} | |||||
var позиция = new THREE.Vector2(); | |||||
var ширина = window.innerWidth * мир.масштаб; | |||||
var высота = window.innerHeight * мир.масштаб; | |||||
позиция.x = ((событие.clientX + window.pageXOffset) / ширина ) * 2 - 1; | |||||
позиция.y = - ((событие.clientY + window.pageYOffset) / высота) * 2 + 1; | |||||
мир.позицияНажатияВРисователе = позиция; | |||||
мир.уведомить("нажатие в рисователе"); | |||||
}; | |||||
// Палец. | |||||
window.addEventListener( | |||||
"touchstart", | |||||
function(событие) { | |||||
уведомитьОНажатии(событие.touches[0]); | |||||
} | |||||
); | |||||
// Мышь. | |||||
window.addEventListener( | |||||
"click", | |||||
function(событие) { | |||||
уведомитьОНажатии(событие); | |||||
} | |||||
); | |||||
// iOS. | |||||
// https://stackoverflow.com/a/31459240/3404710 | |||||
мир.рисователь.domElement.style.cursor = "pointer"; | |||||
}; | |||||
// // // // | |||||
ЗапуститьРисователя = мир => | |||||
{ | |||||
function отрисовать() | |||||
{ | |||||
requestAnimationFrame(отрисовать); | |||||
мир.рисователь.render(мир.сцена, мир.камера); | |||||
} | |||||
отрисовать(); | |||||
}; | |||||
// // // // | |||||
ИзменитьРазмерРисователя = мир => | |||||
{ | |||||
var ширина = window.innerWidth * мир.масштаб; | |||||
var высота = window.innerHeight * мир.масштаб; | |||||
мир.камера.aspect = ширина / высота; | |||||
мир.камера.updateProjectionMatrix(); | |||||
мир.рисователь.setSize(ширина, высота); | |||||
var размер = мир.масштаб * 100; | |||||
мир.канва.style = ` | |||||
position: absolute; | |||||
left: 0; | |||||
top: 0; | |||||
max-width: ${размер}%; | |||||
max-height: ${размер}%; | |||||
width: ${размер}%; | |||||
height: ${размер}%; | |||||
`; | |||||
}; | |||||
// // // // | |||||
ОтслеживатьИзменениеРазмераОкнаБраузера = мир => | |||||
{ | |||||
window.addEventListener( | |||||
"resize", | |||||
function() { | |||||
мир.уведомить("изменили размер окна браузера"); | |||||
} | |||||
); | |||||
}; | |||||
// // // // | |||||
НастроитьРисователя = мир => | |||||
{ | |||||
мир.сцена = new THREE.Scene(); | |||||
мир.камера = new THREE.PerspectiveCamera(45, 1, 0.1, 1000); | |||||
мир.ловец = new THREE.Raycaster(); | |||||
мир.модельер = new THREE.GLTFLoader(); | |||||
мир.текстурщик = new THREE.TextureLoader(); | |||||
мир.масштаб = 1; | |||||
мир.канва = document.createElement("canvas"); | |||||
document.body.prepend(мир.канва); | |||||
мир.рисователь = new THREE.WebGLRenderer({canvas: мир.канва, antialias: true}); | |||||
}; | |||||
// // // // | |||||
УстановитьThreeJS = мир => | |||||
{ | |||||
var модуль = мир.модули.модульПоУказателю(УКАЗАТЕЛЬ_ЭТОГО_МОДУЛЯ); | |||||
var код = модуль.содержимое["/three.js"]; | |||||
var скрипт = document.createElement("script"); | |||||
скрипт.innerHTML = код; | |||||
document.body.appendChild(скрипт); | |||||
}; | |||||
// // // // | |||||
НастроитьРисователяПоУмолчанию = мир => | |||||
{ | |||||
мир.уведомить("надо настроить рисователя по умолчанию"); | |||||
}; |
@@ -0,0 +1,14 @@ | |||||
надо настроить рисователя по умолчанию | |||||
установить ThreeJS | |||||
настроить рисователя | |||||
отслеживать изменение размера окна браузера | |||||
изменить размер рисователя | |||||
отслеживать нажатия в рисователе | |||||
запустить рисователя | |||||
изменили размер окна браузера | |||||
изменить размер рисователя | |||||
изменили масштаб | |||||
изменить размер рисователя | |||||
ручной пуск | |||||
настроить рисователя по умолчанию |
@@ -0,0 +1,49 @@ | |||||
// // // // | |||||
загрузитьМодельЭтогоМодуля = (мир, ресурс, откликУспех, откликПровал = null) => | |||||
{ | |||||
загрузитьМодель(мир, УКАЗАТЕЛЬ_ЭТОГО_МОДУЛЯ, ресурс, откликУспех, откликПровал); | |||||
}; | |||||
// // // // | |||||
загрузитьМодель = (мир, модуль, ресурс, откликУспех, откликПровал = null) => | |||||
{ | |||||
var м = мир.модули.модульПоУказателю(модуль); | |||||
var адрес = `${window.location.origin}${ресурс}`; | |||||
THREE.Cache.enabled = true; | |||||
THREE.Cache.add(адрес, м.содержимое[ресурс]); | |||||
мир.модельер.load( | |||||
адрес, | |||||
function(gltf) { | |||||
// Вычленяем полигональную сетку. | |||||
// Take polygon mesh. | |||||
var успех = false; | |||||
gltf.scene.traverse(function(ребёнок) { | |||||
if (!успех && ребёнок.isMesh) | |||||
{ | |||||
откликУспех(ребёнок); | |||||
успех = true; | |||||
} | |||||
}); | |||||
if (успех) | |||||
{ | |||||
return; | |||||
} | |||||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Отсутствует полигональная сетка ⚬ 不存在多边形网格 ⚬ Polygon mesh is absent"; | |||||
console.error(ошибка, модуль, ресурс); | |||||
откликПровал(); | |||||
}, | |||||
null, | |||||
function(error) { | |||||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Отсутствует ресурс ⚬ 资源不存在 ⚬ Resource is absent"; | |||||
console.error(ошибка, модуль, ресурс); | |||||
откликПровал(); | |||||
} | |||||
); | |||||
}; |
@@ -0,0 +1,54 @@ | |||||
// // // // | |||||
СкрытьКрутилку = мир => | |||||
{ | |||||
document.getElementById("крутилка").style.display = "none"; | |||||
}; | |||||
// // // // | |||||
СоздатьПримерСцены = мир => | |||||
{ | |||||
мир.сцена.background = new THREE.Color(0xFFFFFF); | |||||
var коэффициент = 2; | |||||
var расстояние = 14; | |||||
мир.камера.position.y = расстояние * коэффициент; | |||||
мир.камера.position.z = расстояние; | |||||
мир.камера.lookAt(new THREE.Vector3(0, 0, 0)); | |||||
мир.свет = new THREE.DirectionalLight(0xFFFFFF, 1); | |||||
мир.свет.position.set(-0.5, 1, 0.5).normalize(); | |||||
мир.сцена.add(мир.свет); | |||||
мир.сцена.add(мир.фишка); | |||||
}; | |||||
// // // // | |||||
ЗагрузитьРесурсыСцены = мир => | |||||
{ | |||||
загрузитьМодельЭтогоМодуля( | |||||
мир, | |||||
"/фишка.gltf", | |||||
function(модель) { | |||||
мир.фишка = модель; | |||||
мир.уведомить("загрузили ресурсы сцены"); | |||||
} | |||||
); | |||||
}; | |||||
// // // // | |||||
ВывестиНажатиеВРисователе = мир => | |||||
{ | |||||
console.debug("Нажатие в рисователе:", мир.позицияНажатияВРисователе); | |||||
}; |
@@ -0,0 +1,8 @@ | |||||
пуск | |||||
настроить рисователя по умолчанию | |||||
загрузить ресурсы сцены | |||||
нажатие в рисователе | |||||
вывести нажатие в рисователе | |||||
загрузили ресурсы сцены | |||||
создать пример сцены | |||||
скрыть крутилку |