@@ -1,8 +1,10 @@ | |||
Рисователь | |||
0.3.1 | |||
0.4.0 | |||
https://git.opengamestudio.org/PuCOBATEJlb/PuCOBATEJlb | |||
/base64js.min.js | |||
/three.js | |||
x /⨐.js | |||
x /🎬.js | |||
/🎬.череда | |||
x /📖.js |
@@ -0,0 +1,2 @@ | |||
//https://github.com/beatgammit/base64-js | |||
(function(r){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=r()}else if(typeof define==="function"&&define.amd){define([],r)}else{var e;if(typeof window!=="undefined"){e=window}else if(typeof global!=="undefined"){e=global}else if(typeof self!=="undefined"){e=self}else{e=this}e.base64js=r()}})(function(){var r,e,n;return function(){function d(a,f,i){function u(n,r){if(!f[n]){if(!a[n]){var e="function"==typeof require&&require;if(!r&&e)return e(n,!0);if(v)return v(n,!0);var t=new Error("Cannot find module '"+n+"'");throw t.code="MODULE_NOT_FOUND",t}var o=f[n]={exports:{}};a[n][0].call(o.exports,function(r){var e=a[n][1][r];return u(e||r)},o,o.exports,d,a,f,i)}return f[n].exports}for(var v="function"==typeof require&&require,r=0;r<i.length;r++)u(i[r]);return u}return d}()({"/":[function(r,e,n){"use strict";n.byteLength=f;n.toByteArray=i;n.fromByteArray=p;var u=[];var v=[];var d=typeof Uint8Array!=="undefined"?Uint8Array:Array;var t="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";for(var o=0,a=t.length;o<a;++o){u[o]=t[o];v[t.charCodeAt(o)]=o}v["-".charCodeAt(0)]=62;v["_".charCodeAt(0)]=63;function c(r){var e=r.length;if(e%4>0){throw new Error("Invalid string. Length must be a multiple of 4")}var n=r.indexOf("=");if(n===-1)n=e;var t=n===e?0:4-n%4;return[n,t]}function f(r){var e=c(r);var n=e[0];var t=e[1];return(n+t)*3/4-t}function h(r,e,n){return(e+n)*3/4-n}function i(r){var e;var n=c(r);var t=n[0];var o=n[1];var a=new d(h(r,t,o));var f=0;var i=o>0?t-4:t;var u;for(u=0;u<i;u+=4){e=v[r.charCodeAt(u)]<<18|v[r.charCodeAt(u+1)]<<12|v[r.charCodeAt(u+2)]<<6|v[r.charCodeAt(u+3)];a[f++]=e>>16&255;a[f++]=e>>8&255;a[f++]=e&255}if(o===2){e=v[r.charCodeAt(u)]<<2|v[r.charCodeAt(u+1)]>>4;a[f++]=e&255}if(o===1){e=v[r.charCodeAt(u)]<<10|v[r.charCodeAt(u+1)]<<4|v[r.charCodeAt(u+2)]>>2;a[f++]=e>>8&255;a[f++]=e&255}return a}function s(r){return u[r>>18&63]+u[r>>12&63]+u[r>>6&63]+u[r&63]}function l(r,e,n){var t;var o=[];for(var a=e;a<n;a+=3){t=(r[a]<<16&16711680)+(r[a+1]<<8&65280)+(r[a+2]&255);o.push(s(t))}return o.join("")}function p(r){var e;var n=r.length;var t=n%3;var o=[];var a=16383;for(var f=0,i=n-t;f<i;f+=a){o.push(l(r,f,f+a>i?i:f+a))}if(t===1){e=r[n-1];o.push(u[e>>2]+u[e<<4&63]+"==")}else if(t===2){e=(r[n-2]<<8)+r[n-1];o.push(u[e>>10]+u[e>>4&63]+u[e<<2&63]+"=")}return o.join("")}},{}]},{},[])("/")}); |
@@ -0,0 +1,101 @@ | |||
// // // // | |||
форматИзображенияДляБазы64 = (файл) => | |||
{ | |||
var форматы = { | |||
".png": "png", | |||
".jpg": "jpeg", | |||
".jpeg": "jpeg", | |||
".gif": "gif", | |||
}; | |||
for (var окончание in форматы) | |||
{ | |||
if (файл.toLowerCase().endsWith(окончание)) | |||
{ | |||
return форматы[окончание]; | |||
} | |||
} | |||
return null; | |||
}; | |||
// // // // | |||
загрузитьТекстуру = (мир, указатель, файл, откликУспех, откликПровал = null) => | |||
{ | |||
var модуль = мир.модули.модульПоУказателю(указатель); | |||
var содержимое = модуль.содержимое[файл]; | |||
var представление = мир.база64ИзДвоичногоМассива(new Uint8Array(содержимое)); | |||
var формат = форматИзображенияДляБазы64(файл); | |||
var адрес = `data:image/${формат};base64,${представление}`; | |||
мир.текстурщик.load( | |||
адрес, | |||
function(текстура) { | |||
текстура.flipY = false; | |||
откликУспех(текстура); | |||
}, | |||
null, | |||
function(error) { | |||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Не удалось загрузить текстуру ⚬ 无法加载纹理 ⚬ Could not load texture"; | |||
console.error(ошибка, указатель, файл); | |||
if (откликПровал) | |||
{ | |||
откликПровал(); | |||
} | |||
} | |||
); | |||
}; | |||
// // // // | |||
загрузитьПолигональнуюСетку = (мир, указатель, файл, откликУспех, откликПровал = null) => | |||
{ | |||
var м = мир.модули.модульПоУказателю(указатель); | |||
var адрес = `${window.location.origin}${файл}`; | |||
THREE.Cache.enabled = true; | |||
THREE.Cache.add(адрес, м.содержимое[файл]); | |||
мир.модельер.load( | |||
адрес, | |||
function(gltf) { | |||
THREE.Cache.remove(адрес); | |||
// Вычленяем полигональную сетку. | |||
// Take polygon mesh. | |||
var успех = false; | |||
gltf.scene.traverse(function(ребёнок) { | |||
if (!успех && ребёнок.isMesh) | |||
{ | |||
откликУспех(ребёнок); | |||
успех = true; | |||
} | |||
}); | |||
if (успех) | |||
{ | |||
return; | |||
} | |||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Отсутствует полигональная сетка ⚬ 不存在多边形网格 ⚬ Polygon mesh is absent"; | |||
console.error(ошибка, указатель, файл); | |||
if (откликПровал) | |||
{ | |||
откликПровал(); | |||
} | |||
}, | |||
null, | |||
function(error) { | |||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Не удалось загрузить полигональную сетку ⚬ 无法加载多边形网格 ⚬ Could not load polygon mesh"; | |||
console.error(ошибка, указатель, файл); | |||
if (откликПровал) | |||
{ | |||
откликПровал(); | |||
} | |||
} | |||
); | |||
}; |
@@ -115,6 +115,20 @@ height: ${размер}%; | |||
// // // // | |||
УстановитьBase64JS = мир => | |||
{ | |||
var модуль = мир.модули.модульПоУказателю(УКАЗАТЕЛЬ_ЭТОГО_МОДУЛЯ); | |||
var содержимое = модуль.содержимое["/base64js.min.js"]; | |||
eval(содержимое); | |||
мир.база64ИзДвоичногоМассива = base64js.fromByteArray; | |||
мир.база64ВДвоичныйМассив = base64js.toByteArray; | |||
}; | |||
// // // // | |||
УстановитьThreeJS = мир => | |||
{ | |||
var модуль = мир.модули.модульПоУказателю(УКАЗАТЕЛЬ_ЭТОГО_МОДУЛЯ); | |||
@@ -1,5 +1,6 @@ | |||
ручной пуск | |||
установить ThreeJS | |||
установить Base64JS | |||
настроить рисователя | |||
отслеживать изменение размера окна браузера | |||
изменить размер рисователя | |||
@@ -3,47 +3,60 @@ | |||
// // // // | |||
загрузитьМодельЭтогоМодуля = (мир, ресурс, откликУспех, откликПровал = null) => | |||
ЗагрузитьТекстуры = мир => | |||
{ | |||
загрузитьМодель(мир, УКАЗАТЕЛЬ_ЭТОГО_МОДУЛЯ, ресурс, откликУспех, откликПровал); | |||
var план = 0; | |||
var факт = 0; | |||
for (var указатель in мир.текстуры) | |||
{ | |||
for (var файл in мир.текстуры[указатель]) | |||
{ | |||
++план; | |||
загрузитьТекстуру( | |||
мир, | |||
указатель, | |||
файл, | |||
function(текстура) { | |||
мир.текстуры[указатель][файл] = текстура; | |||
if (++факт == план) | |||
{ | |||
мир.уведомить("загрузили текстуры"); | |||
} | |||
} | |||
); | |||
} | |||
} | |||
}; | |||
// // // // | |||
загрузитьМодель = (мир, модуль, ресурс, откликУспех, откликПровал = 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; | |||
var план = 0; | |||
var факт = 0; | |||
for (var указатель in мир.полигональныеСетки) | |||
{ | |||
for (var файл in мир.полигональныеСетки[указатель]) | |||
{ | |||
++план; | |||
загрузитьПолигональнуюСетку( | |||
мир, | |||
указатель, | |||
файл, | |||
function(сетка) { | |||
мир.полигональныеСетки[указатель][файл] = сетка; | |||
if (++факт == план) | |||
{ | |||
мир.уведомить("загрузили полигональные сетки"); | |||
} | |||
} | |||
}); | |||
if (успех) | |||
{ | |||
return; | |||
} | |||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Отсутствует полигональная сетка ⚬ 不存在多边形网格 ⚬ Polygon mesh is absent"; | |||
console.error(ошибка, модуль, ресурс); | |||
откликПровал(); | |||
}, | |||
null, | |||
function(error) { | |||
var ошибка = "ОШИБКА ⚬ 错误 ⚬ ERROR: Отсутствует ресурс ⚬ 资源不存在 ⚬ Resource is absent"; | |||
console.error(ошибка, модуль, ресурс); | |||
откликПровал(); | |||
); | |||
} | |||
); | |||
} | |||
}; |