mirror of
https://github.com/pissang/claygl.git
synced 2026-02-01 17:27:08 +00:00
wip(type): update entry.
This commit is contained in:
parent
230d95683b
commit
ae01fe6770
@ -1,151 +1,156 @@
|
||||
var glob = require('glob');
|
||||
var fs = require('fs');
|
||||
var path = require('path');
|
||||
console.log('Deprecated.');
|
||||
// var glob = require('glob');
|
||||
// var fs = require('fs');
|
||||
// var path = require('path');
|
||||
|
||||
var ROOT = __dirname + '/../';
|
||||
var SRC_ROOT = ROOT + 'src/';
|
||||
var TS_ROOT = ROOT + 'typescript/';
|
||||
var TS_PORTAL = 'index.d.ts';
|
||||
// var ROOT = __dirname + '/../';
|
||||
// var SRC_ROOT = ROOT + 'src/';
|
||||
// var TS_ROOT = ROOT + 'typescript/';
|
||||
// var TS_PORTAL = 'index.d.ts';
|
||||
|
||||
var OUTPUT_PORTAL = 'claygl.ts';
|
||||
// var OUTPUT_PORTAL = 'claygl.ts';
|
||||
|
||||
var template = fs.readFileSync(__dirname + '/claygl_template.tpl', 'utf-8');
|
||||
// var template = fs.readFileSync(__dirname + '/claygl_template.tpl', 'utf-8');
|
||||
|
||||
var idx = 0;
|
||||
var blacklist = ['shader/builtin', 'app/', 'canvas/', 'gpu/', 'glmatrix/'];
|
||||
// var blacklist = ['shader/builtin', 'app/', 'canvas/', 'gpu/', 'glmatrix/'];
|
||||
|
||||
var topLevelClasses = [
|
||||
'math/BoundingBox',
|
||||
'math/Frustum',
|
||||
'math/Matrix2',
|
||||
'math/Matrix2d',
|
||||
'math/Matrix3',
|
||||
'math/Matrix4',
|
||||
'math/Plane',
|
||||
'math/Quaternion',
|
||||
'math/Ray',
|
||||
'math/Value',
|
||||
'math/Vector2',
|
||||
'math/Vector3',
|
||||
'math/Vector4'
|
||||
];
|
||||
// var topLevelClasses = [
|
||||
// 'math/BoundingBox',
|
||||
// 'math/Frustum',
|
||||
// 'math/Matrix2',
|
||||
// 'math/Matrix2d',
|
||||
// 'math/Matrix3',
|
||||
// 'math/Matrix4',
|
||||
// 'math/Plane',
|
||||
// 'math/Quaternion',
|
||||
// 'math/Ray',
|
||||
// 'math/Value',
|
||||
// 'math/Vector2',
|
||||
// 'math/Vector3',
|
||||
// 'math/Vector4'
|
||||
// ];
|
||||
|
||||
glob(
|
||||
'**/*.ts',
|
||||
{
|
||||
cwd: SRC_ROOT
|
||||
},
|
||||
function (err, files) {
|
||||
var namespace = {};
|
||||
// glob(
|
||||
// '**/*.ts',
|
||||
// {
|
||||
// cwd: SRC_ROOT
|
||||
// },
|
||||
// function (err, files) {
|
||||
// var namespace = {};
|
||||
|
||||
// var tsReferenceList = [];
|
||||
// var basenameCount = {};
|
||||
|
||||
files.forEach(function (file) {
|
||||
var filePathWithOutExt = file.slice(0, -3);
|
||||
if (
|
||||
file.match(/claygl.*?\.ts/) ||
|
||||
file.indexOf('_') >= 0 ||
|
||||
file.endsWith('.glsl.ts') ||
|
||||
blacklist.find(function (item) {
|
||||
return filePathWithOutExt.indexOf(item) >= 0;
|
||||
})
|
||||
) {
|
||||
return;
|
||||
}
|
||||
// files.forEach(function (file) {
|
||||
// var filePathWithOutExt = file.slice(0, -3);
|
||||
// if (
|
||||
// file.match(/claygl.*?\.ts/) ||
|
||||
// file.indexOf('_') >= 0 ||
|
||||
// file.endsWith('.glsl.ts') ||
|
||||
// blacklist.find(function (item) {
|
||||
// return filePathWithOutExt.indexOf(item) >= 0;
|
||||
// })
|
||||
// ) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
var pathArray = filePathWithOutExt.split('/');
|
||||
var baseName = pathArray.pop() + '$' + idx++;
|
||||
// var pathArray = filePathWithOutExt.split('/');
|
||||
// var baseName = pathArray.pop();
|
||||
// basenameCount[baseName] = basenameCount[baseName] || 0;
|
||||
// if (baseName > 0) {
|
||||
// baseName = baseName + basenameCount[baseName];
|
||||
// }
|
||||
// basenameCount[baseName]++;
|
||||
|
||||
var object = pathArray.reduce(function (memo, propName) {
|
||||
if (!memo[propName]) {
|
||||
memo[propName] = {};
|
||||
}
|
||||
return memo[propName];
|
||||
}, namespace);
|
||||
// var object = pathArray.reduce(function (memo, propName) {
|
||||
// if (!memo[propName]) {
|
||||
// memo[propName] = {};
|
||||
// }
|
||||
// return memo[propName];
|
||||
// }, namespace);
|
||||
|
||||
object[baseName] = `import ${baseName} from './${filePathWithOutExt}';`;
|
||||
// object[baseName] = `import ${baseName} from './${filePathWithOutExt}';`;
|
||||
|
||||
// var tsPath = TS_ROOT + filePathWithOutExt + '.d.ts';
|
||||
// // var tsPath = TS_ROOT + filePathWithOutExt + '.d.ts';
|
||||
|
||||
// if (fs.existsSync(tsPath)) {
|
||||
// tsReferenceList.push(filePathWithOutExt);
|
||||
// }
|
||||
});
|
||||
// // if (fs.existsSync(tsPath)) {
|
||||
// // tsReferenceList.push(filePathWithOutExt);
|
||||
// // }
|
||||
// });
|
||||
|
||||
var exportCode = exportPkg(namespace);
|
||||
var output = template.replace(/\{\{\$exportsObject\}\}/, exportCode);
|
||||
// var exportCode = exportPkg(namespace);
|
||||
// var output = template.replace(/\{\{\$exportsObject\}\}/, exportCode);
|
||||
|
||||
fs.writeFileSync(SRC_ROOT + OUTPUT_PORTAL, output, 'utf-8');
|
||||
// fs.writeFileSync(SRC_ROOT + OUTPUT_PORTAL, output, 'utf-8');
|
||||
|
||||
// Write to ts reference file
|
||||
// var referenceCode = tsReferenceList.map(function(path) {
|
||||
// return '///<reference path="typescript/' + path + '" />';
|
||||
// }).join('\n');
|
||||
// fs.writeFileSync(ROOT + TS_PORTAL, referenceCode, 'utf-8');
|
||||
}
|
||||
);
|
||||
// // Write to ts reference file
|
||||
// // var referenceCode = tsReferenceList.map(function(path) {
|
||||
// // return '///<reference path="typescript/' + path + '" />';
|
||||
// // }).join('\n');
|
||||
// // fs.writeFileSync(ROOT + TS_PORTAL, referenceCode, 'utf-8');
|
||||
// }
|
||||
// );
|
||||
|
||||
/**
|
||||
* Export pkg to import/export codes
|
||||
* @param {Object} pkg package to export
|
||||
* @param {Boolean} isChild if it is a child package
|
||||
* @param {String} pkgName name of the package, if it's a child
|
||||
* @param {String[]} externImports imports
|
||||
*/
|
||||
function exportPkg(pkg, isChild, pkgName, externImports) {
|
||||
var keys = Object.keys(pkg);
|
||||
var imports = externImports || [];
|
||||
// /**
|
||||
// * Export pkg to import/export codes
|
||||
// * @param {Object} pkg package to export
|
||||
// * @param {Boolean} isChild if it is a child package
|
||||
// * @param {String} pkgName name of the package, if it's a child
|
||||
// * @param {String[]} externImports imports
|
||||
// */
|
||||
// function exportPkg(pkg, isChild, pkgName, externImports) {
|
||||
// var keys = Object.keys(pkg);
|
||||
// var imports = externImports || [];
|
||||
|
||||
var topLevels = [];
|
||||
var children = keys.map(function (name) {
|
||||
if (isString(pkg[name])) {
|
||||
var className = name.substring(0, name.indexOf('$'));
|
||||
if (
|
||||
topLevelClasses.find(function (item) {
|
||||
return pkg[name].indexOf(item) >= 0;
|
||||
})
|
||||
) {
|
||||
topLevels.push(name);
|
||||
}
|
||||
// a class, not a packagge
|
||||
imports.push(pkg[name]);
|
||||
if (pkgName) {
|
||||
// export as a child class in package
|
||||
// indentation + (key : value)
|
||||
return (isChild ? ' ' : ' ') + className + ': ' + name;
|
||||
} else {
|
||||
// export as a class at root level
|
||||
return `export { ${name} as ${className} };`;
|
||||
}
|
||||
} else {
|
||||
// export as a child package
|
||||
return exportPkg(pkg[name], pkgName && true, name, imports);
|
||||
}
|
||||
});
|
||||
// var topLevels = [];
|
||||
// var children = keys.map(function (name) {
|
||||
// if (isString(pkg[name])) {
|
||||
// var className = name;
|
||||
// if (
|
||||
// topLevelClasses.find(function (item) {
|
||||
// return pkg[name].indexOf(item) >= 0;
|
||||
// })
|
||||
// ) {
|
||||
// topLevels.push(name);
|
||||
// }
|
||||
// // a class, not a packagge
|
||||
// imports.push(pkg[name]);
|
||||
// if (pkgName) {
|
||||
// // export as a child class in package
|
||||
// // indentation + (key : value)
|
||||
// return (isChild ? ' ' : ' ') + className + ': ' + name;
|
||||
// } else {
|
||||
// // export as a class at root level
|
||||
// return `export { ${name} as ${className} };`;
|
||||
// }
|
||||
// } else {
|
||||
// // export as a child package
|
||||
// return exportPkg(pkg[name], pkgName && true, name, imports);
|
||||
// }
|
||||
// });
|
||||
|
||||
var importCode = externImports ? '' : imports.join('\n') + '\n\n';
|
||||
var exportCode;
|
||||
if (pkgName) {
|
||||
if (isChild) {
|
||||
// export as a grand-child package
|
||||
exportCode = ` ${pkgName}: {\n${children.join(',\n')}\n }`;
|
||||
} else {
|
||||
// export as a package at root level
|
||||
exportCode = `\nconst ${pkgName} = {\n${children.join(',\n')}\n};\nexport { ${pkgName} };\n`;
|
||||
}
|
||||
} else {
|
||||
// export child classes
|
||||
exportCode = children.join('\n');
|
||||
}
|
||||
// var importCode = externImports ? '' : imports.join('\n') + '\n\n';
|
||||
// var exportCode;
|
||||
// if (pkgName) {
|
||||
// if (isChild) {
|
||||
// // export as a grand-child package
|
||||
// exportCode = ` ${pkgName}: {\n${children.join(',\n')}\n }`;
|
||||
// } else {
|
||||
// // export as a package at root level
|
||||
// exportCode = `\nconst ${pkgName} = {\n${children.join(',\n')}\n};\nexport { ${pkgName} };\n`;
|
||||
// }
|
||||
// } else {
|
||||
// // export child classes
|
||||
// exportCode = children.join('\n');
|
||||
// }
|
||||
|
||||
topLevels.forEach(function (name) {
|
||||
var className = name.substring(0, name.indexOf('$'));
|
||||
exportCode += `export { ${name} as ${className} };\n`;
|
||||
});
|
||||
// topLevels.forEach(function (name) {
|
||||
// var className = name.substring(0, name.indexOf('$'));
|
||||
// exportCode += `export { ${name} as ${className} };\n`;
|
||||
// });
|
||||
|
||||
return importCode + exportCode;
|
||||
}
|
||||
// return importCode + exportCode;
|
||||
// }
|
||||
|
||||
function isString(s) {
|
||||
return typeof s === 'string';
|
||||
}
|
||||
// function isString(s) {
|
||||
// return typeof s === 'string';
|
||||
// }
|
||||
|
||||
@ -50,7 +50,8 @@
|
||||
"mocha": "^4.0.1",
|
||||
"remap-istanbul": "^0.9.5",
|
||||
"rollup": "^2.70.2",
|
||||
"terser": "^5.12.1"
|
||||
"terser": "^5.12.1",
|
||||
"typescript": "^4.6.4"
|
||||
},
|
||||
"dependencies": {
|
||||
"@rollup/plugin-typescript": "^8.3.2",
|
||||
|
||||
52
pnpm-lock.yaml
generated
52
pnpm-lock.yaml
generated
@ -16,14 +16,15 @@ specifiers:
|
||||
rollup: ^2.70.2
|
||||
terser: ^5.12.1
|
||||
tslib: ^2.3.1
|
||||
typescript: ^4.6.4
|
||||
|
||||
dependencies:
|
||||
'@rollup/plugin-typescript': 8.3.2_rollup@2.70.2+tslib@2.3.1
|
||||
'@rollup/plugin-typescript': 8.3.2_4a24bde9c77b6cb2b1da67564afd9101
|
||||
tslib: 2.3.1
|
||||
|
||||
devDependencies:
|
||||
'@typescript-eslint/eslint-plugin': 5.20.0_659090a1a2f507e2e971a348ed10736d
|
||||
'@typescript-eslint/parser': 5.20.0_eslint@8.13.0
|
||||
'@typescript-eslint/eslint-plugin': 5.20.0_bd994e352ae473ad3e507fadfa78fd8c
|
||||
'@typescript-eslint/parser': 5.20.0_eslint@8.13.0+typescript@4.6.4
|
||||
electron: 1.7.9
|
||||
electron-mocha: 4.0.3
|
||||
eslint: 8.13.0
|
||||
@ -35,6 +36,7 @@ devDependencies:
|
||||
remap-istanbul: 0.9.6
|
||||
rollup: 2.70.2
|
||||
terser: 5.12.1
|
||||
typescript: 4.6.4
|
||||
|
||||
packages:
|
||||
|
||||
@ -91,7 +93,7 @@ packages:
|
||||
fastq: 1.13.0
|
||||
dev: true
|
||||
|
||||
/@rollup/plugin-typescript/8.3.2_rollup@2.70.2+tslib@2.3.1:
|
||||
/@rollup/plugin-typescript/8.3.2_4a24bde9c77b6cb2b1da67564afd9101:
|
||||
resolution: {integrity: sha512-MtgyR5LNHZr3GyN0tM7gNO9D0CS+Y+vflS4v/PHmrX17JCkHUYKvQ5jN5o3cz1YKllM3duXUqu3yOHwMPUxhDg==}
|
||||
engines: {node: '>=8.0.0'}
|
||||
peerDependencies:
|
||||
@ -103,6 +105,7 @@ packages:
|
||||
resolve: 1.22.0
|
||||
rollup: 2.70.2
|
||||
tslib: 2.3.1
|
||||
typescript: 4.6.4
|
||||
dev: false
|
||||
|
||||
/@rollup/pluginutils/3.1.0_rollup@2.70.2:
|
||||
@ -129,7 +132,7 @@ packages:
|
||||
resolution: {integrity: sha512-29GS75BE8asnTno3yB6ubOJOO0FboExEqNJy4bpz0GSmW/8wPTNL4h9h63c6s1uTrOopCmJYe/4yJLh5r92ZUA==}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/eslint-plugin/5.20.0_659090a1a2f507e2e971a348ed10736d:
|
||||
/@typescript-eslint/eslint-plugin/5.20.0_bd994e352ae473ad3e507fadfa78fd8c:
|
||||
resolution: {integrity: sha512-fapGzoxilCn3sBtC6NtXZX6+P/Hef7VDbyfGqTTpzYydwhlkevB+0vE0EnmHPVTVSy68GUncyJ/2PcrFBeCo5Q==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -140,22 +143,23 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/parser': 5.20.0_eslint@8.13.0
|
||||
'@typescript-eslint/parser': 5.20.0_eslint@8.13.0+typescript@4.6.4
|
||||
'@typescript-eslint/scope-manager': 5.20.0
|
||||
'@typescript-eslint/type-utils': 5.20.0_eslint@8.13.0
|
||||
'@typescript-eslint/utils': 5.20.0_eslint@8.13.0
|
||||
'@typescript-eslint/type-utils': 5.20.0_eslint@8.13.0+typescript@4.6.4
|
||||
'@typescript-eslint/utils': 5.20.0_eslint@8.13.0+typescript@4.6.4
|
||||
debug: 4.3.4
|
||||
eslint: 8.13.0
|
||||
functional-red-black-tree: 1.0.1
|
||||
ignore: 5.2.0
|
||||
regexpp: 3.2.0
|
||||
semver: 7.3.7
|
||||
tsutils: 3.21.0
|
||||
tsutils: 3.21.0_typescript@4.6.4
|
||||
typescript: 4.6.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/parser/5.20.0_eslint@8.13.0:
|
||||
/@typescript-eslint/parser/5.20.0_eslint@8.13.0+typescript@4.6.4:
|
||||
resolution: {integrity: sha512-UWKibrCZQCYvobmu3/N8TWbEeo/EPQbS41Ux1F9XqPzGuV7pfg6n50ZrFo6hryynD8qOTTfLHtHjjdQtxJ0h/w==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -167,9 +171,10 @@ packages:
|
||||
dependencies:
|
||||
'@typescript-eslint/scope-manager': 5.20.0
|
||||
'@typescript-eslint/types': 5.20.0
|
||||
'@typescript-eslint/typescript-estree': 5.20.0
|
||||
'@typescript-eslint/typescript-estree': 5.20.0_typescript@4.6.4
|
||||
debug: 4.3.4
|
||||
eslint: 8.13.0
|
||||
typescript: 4.6.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -182,7 +187,7 @@ packages:
|
||||
'@typescript-eslint/visitor-keys': 5.20.0
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/type-utils/5.20.0_eslint@8.13.0:
|
||||
/@typescript-eslint/type-utils/5.20.0_eslint@8.13.0+typescript@4.6.4:
|
||||
resolution: {integrity: sha512-WxNrCwYB3N/m8ceyoGCgbLmuZwupvzN0rE8NBuwnl7APgjv24ZJIjkNzoFBXPRCGzLNkoU/WfanW0exvp/+3Iw==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -192,10 +197,11 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
dependencies:
|
||||
'@typescript-eslint/utils': 5.20.0_eslint@8.13.0
|
||||
'@typescript-eslint/utils': 5.20.0_eslint@8.13.0+typescript@4.6.4
|
||||
debug: 4.3.4
|
||||
eslint: 8.13.0
|
||||
tsutils: 3.21.0
|
||||
tsutils: 3.21.0_typescript@4.6.4
|
||||
typescript: 4.6.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
@ -205,7 +211,7 @@ packages:
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/typescript-estree/5.20.0:
|
||||
/@typescript-eslint/typescript-estree/5.20.0_typescript@4.6.4:
|
||||
resolution: {integrity: sha512-36xLjP/+bXusLMrT9fMMYy1KJAGgHhlER2TqpUVDYUQg4w0q/NW/sg4UGAgVwAqb8V4zYg43KMUpM8vV2lve6w==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -220,12 +226,13 @@ packages:
|
||||
globby: 11.1.0
|
||||
is-glob: 4.0.3
|
||||
semver: 7.3.7
|
||||
tsutils: 3.21.0
|
||||
tsutils: 3.21.0_typescript@4.6.4
|
||||
typescript: 4.6.4
|
||||
transitivePeerDependencies:
|
||||
- supports-color
|
||||
dev: true
|
||||
|
||||
/@typescript-eslint/utils/5.20.0_eslint@8.13.0:
|
||||
/@typescript-eslint/utils/5.20.0_eslint@8.13.0+typescript@4.6.4:
|
||||
resolution: {integrity: sha512-lHONGJL1LIO12Ujyx8L8xKbwWSkoUKFSO+0wDAqGXiudWB2EO7WEUT+YZLtVbmOmSllAjLb9tpoIPwpRe5Tn6w==}
|
||||
engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
|
||||
peerDependencies:
|
||||
@ -234,7 +241,7 @@ packages:
|
||||
'@types/json-schema': 7.0.11
|
||||
'@typescript-eslint/scope-manager': 5.20.0
|
||||
'@typescript-eslint/types': 5.20.0
|
||||
'@typescript-eslint/typescript-estree': 5.20.0
|
||||
'@typescript-eslint/typescript-estree': 5.20.0_typescript@4.6.4
|
||||
eslint: 8.13.0
|
||||
eslint-scope: 5.1.1
|
||||
eslint-utils: 3.0.0_eslint@8.13.0
|
||||
@ -2663,13 +2670,14 @@ packages:
|
||||
resolution: {integrity: sha512-77EbyPPpMz+FRFRuAFlWMtmgUWGe9UOG2Z25NqCwiIjRhOf5iKGuzSe5P2w1laq+FkRy4p+PCuVkJSGkzTEKVw==}
|
||||
dev: false
|
||||
|
||||
/tsutils/3.21.0:
|
||||
/tsutils/3.21.0_typescript@4.6.4:
|
||||
resolution: {integrity: sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA==}
|
||||
engines: {node: '>= 6'}
|
||||
peerDependencies:
|
||||
typescript: '>=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta'
|
||||
dependencies:
|
||||
tslib: 1.14.1
|
||||
typescript: 4.6.4
|
||||
dev: true
|
||||
|
||||
/tunnel-agent/0.6.0:
|
||||
@ -2705,6 +2713,12 @@ packages:
|
||||
resolution: {integrity: sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c=}
|
||||
dev: true
|
||||
|
||||
/typescript/4.6.4:
|
||||
resolution: {integrity: sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg==}
|
||||
engines: {node: '>=4.2.0'}
|
||||
hasBin: true
|
||||
dev: true
|
||||
|
||||
/uglify-js/3.15.4:
|
||||
resolution: {integrity: sha512-vMOPGDuvXecPs34V74qDKk4iJ/SN4vL3Ow/23ixafENYvtrNvtbcgUeugTcUGRGsOF/5fU8/NYSL5Hyb3l1OJA==}
|
||||
engines: {node: '>=0.8.0'}
|
||||
|
||||
@ -5,7 +5,7 @@ import Ray from './math/Ray';
|
||||
|
||||
import * as vec4 from './glmatrix/vec4';
|
||||
import * as vec3 from './glmatrix/vec3';
|
||||
import { Vector2 } from './claygl';
|
||||
import Vector2 from './math/Vector2';
|
||||
|
||||
export interface CameraOpts extends ClayNodeOpts {}
|
||||
|
||||
@ -31,12 +31,6 @@ class Camera extends ClayNode {
|
||||
*/
|
||||
frustum = new Frustum();
|
||||
|
||||
constructor(opts: Partial<ClayNodeOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
super.update.call(this);
|
||||
Matrix4.invert(this.viewMatrix, this.worldTransform);
|
||||
|
||||
@ -49,10 +49,9 @@ class InstancedMesh extends Mesh {
|
||||
private _attributesSymbols: string[] = [];
|
||||
|
||||
constructor(opts?: Partial<InstancedMeshOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
|
||||
this.instances = optional(opts.instances, []);
|
||||
this.instances = optional(opts && opts.instances, []);
|
||||
this.createInstancedAttribute('instanceMat1', 'float', 4, 1);
|
||||
this.createInstancedAttribute('instanceMat2', 'float', 4, 1);
|
||||
this.createInstancedAttribute('instanceMat3', 'float', 4, 1);
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
import Base from './core/Base';
|
||||
import { optional } from './core/util';
|
||||
import type ClayNode from './Node';
|
||||
|
||||
|
||||
@ -56,7 +56,6 @@ class Light extends ClayNode {
|
||||
>;
|
||||
|
||||
constructor(opts?: Partial<LightOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
}
|
||||
|
||||
@ -24,8 +24,8 @@ class Mesh extends Renderable {
|
||||
offsetMatrix?: Matrix4;
|
||||
|
||||
constructor(opts?: Partial<MeshOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
opts = opts || {};
|
||||
if (opts.skeleton) {
|
||||
this.skeleton = opts.skeleton;
|
||||
}
|
||||
|
||||
20
src/Node.ts
20
src/Node.ts
@ -89,7 +89,7 @@ class ClayNode extends Notifier {
|
||||
/**
|
||||
* The root scene mounted. Null if it is a isolated node
|
||||
*/
|
||||
protected _scene: Scene;
|
||||
protected _scene?: Scene;
|
||||
|
||||
private _inIterating = false;
|
||||
|
||||
@ -135,12 +135,6 @@ class ClayNode extends Notifier {
|
||||
* @param {string} name
|
||||
*/
|
||||
setName(name: string) {
|
||||
const scene = this._scene;
|
||||
if (scene) {
|
||||
const nodeRepository = scene._nodeRepository;
|
||||
delete nodeRepository[this.name];
|
||||
nodeRepository[name] = this;
|
||||
}
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
@ -194,7 +188,7 @@ class ClayNode extends Notifier {
|
||||
children[idx]._parent = undefined;
|
||||
|
||||
if (this._scene) {
|
||||
children[idx].traverse(this._removeSelfFromScene, this);
|
||||
children[idx].traverse((child) => this._removeSelfFromScene(child));
|
||||
}
|
||||
}
|
||||
|
||||
@ -218,12 +212,12 @@ class ClayNode extends Notifier {
|
||||
}
|
||||
|
||||
_removeSelfFromScene(descendant: ClayNode) {
|
||||
descendant._scene.removeFromScene(descendant);
|
||||
descendant._scene = null;
|
||||
descendant._scene!.removeFromScene(descendant);
|
||||
descendant._scene = undefined;
|
||||
}
|
||||
|
||||
_addSelfToScene(descendant: ClayNode) {
|
||||
this._scene.addToScene(descendant);
|
||||
this._scene!.addToScene(descendant);
|
||||
descendant._scene = this._scene;
|
||||
}
|
||||
|
||||
@ -508,7 +502,7 @@ class ClayNode extends Notifier {
|
||||
* @return {clay.BoundingBox}
|
||||
*/
|
||||
// TODO Skinning
|
||||
getBoundingBox(filter: GetBoundingBoxFilter, out?: BoundingBox): BoundingBox {
|
||||
getBoundingBox(filter?: GetBoundingBoxFilter, out?: BoundingBox): BoundingBox {
|
||||
out = out || new BoundingBox();
|
||||
filter = filter || defaultBoundingBoxNodeFilter;
|
||||
const invWorldTransform = tmpMat4;
|
||||
@ -521,7 +515,7 @@ class ClayNode extends Notifier {
|
||||
|
||||
this.traverse(function (mesh) {
|
||||
const geo = (mesh as Mesh).geometry;
|
||||
if (geo && geo.boundingBox && filter(mesh)) {
|
||||
if (geo && geo.boundingBox && filter(mesh as Mesh)) {
|
||||
tmpBBox.copy(geo.boundingBox);
|
||||
Matrix4.multiply(tmpMat4, invWorldTransform, mesh.worldTransform);
|
||||
tmpBBox.applyTransform(tmpMat4);
|
||||
|
||||
@ -106,8 +106,8 @@ class Renderable extends ClayNode {
|
||||
__depth = 0;
|
||||
|
||||
constructor(opts?: Partial<RenderableOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
opts = opts || {};
|
||||
|
||||
for (let i = 0; i < properties.length; i++) {
|
||||
const name = properties[i];
|
||||
|
||||
@ -330,8 +330,8 @@ class Renderer extends Notifier {
|
||||
private _programMgr: ProgramManager;
|
||||
|
||||
constructor(opts?: Partial<RendererOpts>) {
|
||||
opts = opts || {};
|
||||
super();
|
||||
opts = opts || {};
|
||||
|
||||
const canvas = (this.canvas = opts.canvas || vendor.createCanvas());
|
||||
try {
|
||||
|
||||
@ -40,7 +40,11 @@ function getProgramKey(lightNumbers: Record<string, number>) {
|
||||
return id;
|
||||
}
|
||||
|
||||
function setUniforms(uniforms: Record<string, ShaderUniform>, program, renderer: Renderer) {
|
||||
function setUniforms(
|
||||
uniforms: Record<string, ShaderUniform>,
|
||||
program: GLProgram,
|
||||
renderer: Renderer
|
||||
) {
|
||||
for (const symbol in uniforms) {
|
||||
const lu = uniforms[symbol];
|
||||
if (lu.type === 'tv') {
|
||||
@ -135,10 +139,9 @@ class Scene extends ClayNode {
|
||||
private _renderLists = new LRUCache<RenderList>(20);
|
||||
|
||||
constructor(opts?: Partial<SceneOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
|
||||
this.material = opts.material;
|
||||
this.material = opts && opts.material;
|
||||
|
||||
this._scene = this;
|
||||
}
|
||||
|
||||
@ -8,8 +8,8 @@ import * as mat4 from './glmatrix/mat4';
|
||||
import * as vec3 from './glmatrix/vec3';
|
||||
import * as quat from './glmatrix/quat';
|
||||
import type ClayNode from './Node';
|
||||
import type SkinningClip from './animation/SkinningClip';
|
||||
import type Geometry from './Geometry';
|
||||
import TrackAnimator from './animation/TrackAnimator';
|
||||
|
||||
const tmpBoundingBox = new BoundingBox();
|
||||
const tmpMat4 = new Matrix4();
|
||||
@ -40,9 +40,9 @@ class Skeleton {
|
||||
*/
|
||||
boundingBox?: BoundingBox;
|
||||
|
||||
private _clips: {
|
||||
private _animations: {
|
||||
maps: number[];
|
||||
clip: SkinningClip;
|
||||
animator: TrackAnimator;
|
||||
}[] = [];
|
||||
|
||||
// Matrix to joint space (relative to root joint)
|
||||
@ -70,13 +70,13 @@ class Skeleton {
|
||||
|
||||
/**
|
||||
* Add a skinning clip and create a map between clip and skeleton
|
||||
* @param clip
|
||||
* @param animator
|
||||
* @param mapRule Map between joint name in skeleton and joint name in clip
|
||||
*/
|
||||
addClip(clip: SkinningClip, mapRule?: Record<string, string>) {
|
||||
addAnimator(animator: TrackAnimator, mapRule?: Record<string, string>) {
|
||||
// Clip have been exists in
|
||||
for (let i = 0; i < this._clips.length; i++) {
|
||||
if (this._clips[i].clip === clip) {
|
||||
for (let i = 0; i < this._animations.length; i++) {
|
||||
if (this._animations[i].animator === animator) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -86,10 +86,10 @@ class Skeleton {
|
||||
maps[i] = -1;
|
||||
}
|
||||
// Create avatar
|
||||
for (let i = 0; i < clip.tracks.length; i++) {
|
||||
for (let i = 0; i < animator.tracks.length; i++) {
|
||||
for (let j = 0; j < this.joints.length; j++) {
|
||||
const joint = this.joints[j];
|
||||
const track = clip.tracks[i];
|
||||
const track = animator.tracks[i];
|
||||
let jointName = joint.name;
|
||||
if (mapRule) {
|
||||
jointName = mapRule[jointName];
|
||||
@ -101,51 +101,51 @@ class Skeleton {
|
||||
}
|
||||
}
|
||||
|
||||
this._clips.push({
|
||||
this._animations.push({
|
||||
maps: maps,
|
||||
clip: clip
|
||||
animator: animator
|
||||
});
|
||||
|
||||
return this._clips.length - 1;
|
||||
return this._animations.length - 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param clip
|
||||
* @param animator
|
||||
*/
|
||||
removeClip(clip: SkinningClip) {
|
||||
removeAnimator(animator: TrackAnimator) {
|
||||
let idx = -1;
|
||||
for (let i = 0; i < this._clips.length; i++) {
|
||||
if (this._clips[i].clip === clip) {
|
||||
for (let i = 0; i < this._animations.length; i++) {
|
||||
if (this._animations[i].animator === animator) {
|
||||
idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (idx > 0) {
|
||||
this._clips.splice(idx, 1);
|
||||
this._animations.splice(idx, 1);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Remove all clips
|
||||
*/
|
||||
removeClipsAll() {
|
||||
this._clips = [];
|
||||
removeAnimatorsAll() {
|
||||
this._animations = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get clip by index
|
||||
* Get animator by index
|
||||
* @param index
|
||||
*/
|
||||
getClip(index: number) {
|
||||
if (this._clips[index]) {
|
||||
return this._clips[index].clip;
|
||||
getAnimator(index: number) {
|
||||
if (this._animations[index]) {
|
||||
return this._animations[index].animator;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return clips number
|
||||
*/
|
||||
getClipsCount() {
|
||||
return this._clips.length;
|
||||
getAnimatorsCount() {
|
||||
return this._animations.length;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -338,16 +338,16 @@ class Skeleton {
|
||||
}
|
||||
|
||||
_setPose() {
|
||||
if (this._clips[0]) {
|
||||
const clip = this._clips[0].clip;
|
||||
const maps = this._clips[0].maps;
|
||||
if (this._animations[0]) {
|
||||
const animator = this._animations[0].animator;
|
||||
const maps = this._animations[0].maps;
|
||||
|
||||
for (let i = 0; i < this.joints.length; i++) {
|
||||
const joint = this.joints[i];
|
||||
if (maps[i] === -1) {
|
||||
continue;
|
||||
}
|
||||
const pose = clip.tracks[maps[i]];
|
||||
const pose = animator.tracks[maps[i]];
|
||||
const node = joint.node;
|
||||
if (node) {
|
||||
// Not update if there is no data.
|
||||
|
||||
@ -2,7 +2,6 @@ import Texture, { TextureImageSource, TextureOpts, TexturePixelSource } from './
|
||||
import glenum from './core/glenum';
|
||||
import vendor from './core/vendor';
|
||||
import Renderer from './Renderer';
|
||||
import * as mathUtil from './math/util';
|
||||
import { GLEnum } from './core/type';
|
||||
|
||||
function nearestPowerOfTwo(val: number) {
|
||||
@ -112,11 +111,6 @@ class Texture2D extends Texture {
|
||||
}
|
||||
}
|
||||
|
||||
constructor(opts?: Partial<Texture2DOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
}
|
||||
|
||||
update(renderer: Renderer) {
|
||||
const _gl = renderer.gl;
|
||||
_gl.bindTexture(_gl.TEXTURE_2D, this._cache.get('webgl_texture'));
|
||||
|
||||
@ -21,7 +21,7 @@ export interface TextureCubeOpts extends TextureOpts, TextureCubeData {
|
||||
/**
|
||||
* @type {Array.<Object>}
|
||||
*/
|
||||
mipmaps: TextureCubeData[];
|
||||
mipmaps?: TextureCubeData[];
|
||||
}
|
||||
|
||||
interface TextureCube extends TextureCubeOpts {}
|
||||
@ -54,10 +54,6 @@ interface TextureCube extends TextureCubeOpts {}
|
||||
*/
|
||||
class TextureCube extends Texture {
|
||||
readonly textureType = 'textureCube';
|
||||
constructor(opts?: Partial<TextureCubeOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
}
|
||||
|
||||
get width() {
|
||||
const images = this.image;
|
||||
@ -103,6 +99,7 @@ class TextureCube extends Texture {
|
||||
this.updateCommon(renderer);
|
||||
|
||||
const glFormat = this.format;
|
||||
const mipmaps = this.mipmaps;
|
||||
let glType = this.type;
|
||||
|
||||
_gl.texParameteri(_gl.TEXTURE_CUBE_MAP, _gl.TEXTURE_WRAP_S, this.getAvailableWrapS());
|
||||
@ -128,11 +125,11 @@ class TextureCube extends Texture {
|
||||
}
|
||||
}
|
||||
|
||||
if (this.mipmaps.length) {
|
||||
if (mipmaps && mipmaps.length) {
|
||||
let width = this.width;
|
||||
let height = this.height;
|
||||
for (let i = 0; i < this.mipmaps.length; i++) {
|
||||
const mipmap = this.mipmaps[i];
|
||||
for (let i = 0; i < mipmaps.length; i++) {
|
||||
const mipmap = mipmaps[i];
|
||||
this._updateTextureData(_gl, mipmap, i, width, height, glFormat, glType);
|
||||
width /= 2;
|
||||
height /= 2;
|
||||
|
||||
@ -54,9 +54,7 @@ export default class Timeline extends Notifier {
|
||||
constructor(opts?: TimelineOption) {
|
||||
super();
|
||||
|
||||
opts = opts || {};
|
||||
|
||||
this.stage = opts.stage || {};
|
||||
this.stage = (opts && opts.stage) || {};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -1,6 +1,11 @@
|
||||
import Timeline from '../Timeline';
|
||||
import Clip from './Clip';
|
||||
|
||||
/**
|
||||
* Animator will control animation play.
|
||||
*
|
||||
* We don't name it Animation to avoid conflicts with DOM API.
|
||||
*/
|
||||
export interface Animator {
|
||||
timeline?: Timeline;
|
||||
|
||||
|
||||
@ -29,16 +29,12 @@ class Blend1DAnimator extends BlendAnimator {
|
||||
private _cacheKey: number = 0;
|
||||
private _cachePosition: number = -Infinity;
|
||||
|
||||
private _loop?: boolean;
|
||||
|
||||
private _elpasedTime?: number;
|
||||
|
||||
protected _output?: BlendAnimatorTarget;
|
||||
protected _inputs: Blend1DAnimatorInput[];
|
||||
|
||||
constructor(opts?: Partial<Blend1DAnimatorOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
opts = opts || {};
|
||||
|
||||
this._inputs = (opts.inputs || []).sort(clipSortFunc);
|
||||
this._output = opts.output;
|
||||
|
||||
@ -3,11 +3,6 @@
|
||||
import Vector2 from '../math/Vector2';
|
||||
import delaunay from '../util/delaunay';
|
||||
import { BlendAnimator, BlendAnimatorOpts, BlendAnimatorTarget } from './BlendAnimator';
|
||||
import Clip from './Clip';
|
||||
|
||||
const clipSortFunc = function (a: { position: number }, b: { position: number }) {
|
||||
return a.position - b.position;
|
||||
};
|
||||
|
||||
interface Blend2DAnimatorInput {
|
||||
position: Vector2;
|
||||
@ -32,9 +27,6 @@ interface Triangle {
|
||||
class Blend2DAnimator extends BlendAnimator {
|
||||
position = new Vector2();
|
||||
|
||||
private _cacheKey: number = 0;
|
||||
private _cachePosition: number = -Infinity;
|
||||
|
||||
protected _output?: BlendAnimatorTarget;
|
||||
protected _inputs: Blend2DAnimatorInput[];
|
||||
|
||||
@ -42,9 +34,8 @@ class Blend2DAnimator extends BlendAnimator {
|
||||
private _triangles?: Triangle[];
|
||||
|
||||
constructor(opts?: Partial<Blend2DAnimatorOpts>) {
|
||||
opts = opts || {};
|
||||
|
||||
super();
|
||||
opts = opts || {};
|
||||
|
||||
this._inputs = opts.inputs || [];
|
||||
this._output = opts.output;
|
||||
|
||||
@ -22,8 +22,9 @@ class OrthographicCamera extends Camera {
|
||||
bottom = -1;
|
||||
|
||||
constructor(opts?: Partial<OrthographicCameraOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts || {});
|
||||
this.update();
|
||||
}
|
||||
|
||||
updateProjectionMatrix() {
|
||||
@ -40,7 +41,7 @@ class OrthographicCamera extends Camera {
|
||||
this.far = -(1 - m[14]) / m[10];
|
||||
}
|
||||
clone() {
|
||||
const camera = super.call(this);
|
||||
const camera = super.clone.call(this);
|
||||
camera.left = this.left;
|
||||
camera.right = this.right;
|
||||
camera.near = this.near;
|
||||
|
||||
@ -27,6 +27,12 @@ class PerspectiveCamera extends Camera {
|
||||
near = 0.1;
|
||||
far = 2000;
|
||||
|
||||
constructor(opts?: Partial<PerspectiveCameraOpts>) {
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.update();
|
||||
}
|
||||
|
||||
updateProjectionMatrix() {
|
||||
const rad = (this.fov / 180) * Math.PI;
|
||||
this.projectionMatrix.perspective(rad, this.aspect, this.near, this.far);
|
||||
|
||||
4
src/camera/index.ts
Normal file
4
src/camera/index.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import Orthographic from './Orthographic';
|
||||
import Perspective from './Perspective';
|
||||
|
||||
export { Orthographic, Perspective };
|
||||
47
src/claygl.ts
Normal file
47
src/claygl.ts
Normal file
@ -0,0 +1,47 @@
|
||||
export { default as Renderer } from './Renderer';
|
||||
export { default as Material } from './Material';
|
||||
export { default as Shader } from './Shader';
|
||||
export { default as Geometry } from './Geometry';
|
||||
export { default as Node } from './Node';
|
||||
export { default as Renderable } from './Renderable';
|
||||
export { default as Mesh } from './Mesh';
|
||||
export { default as InstancedMesh } from './InstancedMesh';
|
||||
export { default as GeometryBase } from './GeometryBase';
|
||||
export { default as Skeleton } from './Skeleton';
|
||||
export { default as Joint } from './Joint';
|
||||
export { default as FrameBuffer } from './FrameBuffer';
|
||||
export { default as Scene } from './Scene';
|
||||
export { default as Timeline } from './Timeline';
|
||||
export { default as Texture2D } from './Texture2D';
|
||||
export { default as TextureCube } from './TextureCube';
|
||||
|
||||
export {
|
||||
Perspective as PerspectiveCamera,
|
||||
Orthographic as OrthographicCamera
|
||||
} from './camera/index';
|
||||
|
||||
export {
|
||||
Ambient as AmbientLight,
|
||||
AmbientCubemap as AmbientCubemapLight,
|
||||
AmbientSH as AmbientSHLight,
|
||||
Directional as DirectionalLight,
|
||||
Point as PointLight,
|
||||
Sphere as SphereLight,
|
||||
Spot as SpotLight,
|
||||
Tube as TubeLight
|
||||
} from './light/index';
|
||||
|
||||
export {
|
||||
Cone as ConeGeometry,
|
||||
Cube as CubeGeometry,
|
||||
Cylinder as CylinderGeometry,
|
||||
ParametricSurface as ParametricSurfaceGeometry,
|
||||
Plane as PlaneGeometry,
|
||||
Sphere as SphereGeometry
|
||||
} from './geometry/index';
|
||||
|
||||
export * from './math';
|
||||
|
||||
export { color } from './core';
|
||||
|
||||
export * as easing from './animation/easing';
|
||||
@ -1,5 +1,3 @@
|
||||
// @ts-nocheck
|
||||
import Base from '../core/Base';
|
||||
import OrthoCamera from '../camera/Orthographic';
|
||||
import Plane from '../geometry/Plane';
|
||||
import Shader from '../Shader';
|
||||
@ -7,6 +5,12 @@ import Material from '../Material';
|
||||
import Mesh from '../Mesh';
|
||||
import glenum from '../core/glenum';
|
||||
import vertexGlsl from '../shader/source/compositor/vertex.glsl.js';
|
||||
import { GLEnum } from '../core/type';
|
||||
import { optional } from '../core/util';
|
||||
import type Renderer from '../Renderer';
|
||||
import type FrameBuffer from '../FrameBuffer';
|
||||
import type Texture2D from '../Texture2D';
|
||||
import Notifier from '../core/Notifier';
|
||||
|
||||
Shader.import(vertexGlsl);
|
||||
|
||||
@ -17,187 +21,148 @@ const mesh = new Mesh({
|
||||
});
|
||||
const camera = new OrthoCamera();
|
||||
|
||||
/**
|
||||
* @constructor clay.compositor.Pass
|
||||
* @extends clay.core.Base
|
||||
*/
|
||||
const Pass = Base.extend(
|
||||
function () {
|
||||
return /** @lends clay.compositor.Pass# */ {
|
||||
/**
|
||||
* Fragment shader string
|
||||
* @type {string}
|
||||
*/
|
||||
// PENDING shader or fragment ?
|
||||
fragment: '',
|
||||
interface CompositorFullscreenQuadPassOpts {
|
||||
clearColor?: boolean;
|
||||
clearDepth?: boolean;
|
||||
blendWithPrevious?: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {Object}
|
||||
*/
|
||||
outputs: null,
|
||||
class CompositorFullscreenQuadPass extends Notifier {
|
||||
material: Material;
|
||||
|
||||
/**
|
||||
* @type {clay.Material}
|
||||
*/
|
||||
material: null,
|
||||
clearColor?: boolean;
|
||||
clearDepth?: boolean;
|
||||
blendWithPrevious?: boolean;
|
||||
|
||||
/**
|
||||
* @type {Boolean}
|
||||
*/
|
||||
blendWithPrevious: false,
|
||||
outputs: Record<string, Texture2D | undefined> = {};
|
||||
|
||||
/**
|
||||
* @type {Boolean}
|
||||
*/
|
||||
clearColor: false,
|
||||
constructor(fragment: string, opts?: Partial<CompositorFullscreenQuadPassOpts>) {
|
||||
super();
|
||||
|
||||
/**
|
||||
* @type {Boolean}
|
||||
*/
|
||||
clearDepth: true
|
||||
};
|
||||
},
|
||||
function () {
|
||||
const shader = new Shader(Shader.source('clay.compositor.vertex'), this.fragment);
|
||||
const shader = new Shader(Shader.source('clay.compositor.vertex'), fragment);
|
||||
const material = new Material({
|
||||
shader: shader
|
||||
});
|
||||
material.enableTexturesAll();
|
||||
|
||||
this.material = material;
|
||||
},
|
||||
/** @lends clay.compositor.Pass.prototype */
|
||||
{
|
||||
/**
|
||||
* @param {string} name
|
||||
* @param {} value
|
||||
*/
|
||||
setUniform: function (name, value) {
|
||||
this.material.setUniform(name, value);
|
||||
},
|
||||
/**
|
||||
* @param {string} name
|
||||
* @return {}
|
||||
*/
|
||||
getUniform: function (name) {
|
||||
const uniform = this.material.uniforms[name];
|
||||
if (uniform) {
|
||||
return uniform.value;
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {clay.Texture} texture
|
||||
* @param {number} attachment
|
||||
*/
|
||||
attachOutput: function (texture, attachment) {
|
||||
if (!this.outputs) {
|
||||
this.outputs = {};
|
||||
}
|
||||
attachment = attachment || glenum.COLOR_ATTACHMENT0;
|
||||
this.outputs[attachment] = texture;
|
||||
},
|
||||
/**
|
||||
* @param {clay.Texture} texture
|
||||
*/
|
||||
detachOutput: function (texture) {
|
||||
for (const attachment in this.outputs) {
|
||||
if (this.outputs[attachment] === texture) {
|
||||
this.outputs[attachment] = null;
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
bind: function (renderer, frameBuffer) {
|
||||
if (this.outputs) {
|
||||
for (const attachment in this.outputs) {
|
||||
const texture = this.outputs[attachment];
|
||||
if (texture) {
|
||||
frameBuffer.attach(texture, attachment);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (frameBuffer) {
|
||||
frameBuffer.bind(renderer);
|
||||
}
|
||||
},
|
||||
|
||||
unbind: function (renderer, frameBuffer) {
|
||||
frameBuffer.unbind(renderer);
|
||||
},
|
||||
/**
|
||||
* @param {clay.Renderer} renderer
|
||||
* @param {clay.FrameBuffer} [frameBuffer]
|
||||
*/
|
||||
render: function (renderer, frameBuffer) {
|
||||
const _gl = renderer.gl;
|
||||
|
||||
if (frameBuffer) {
|
||||
this.bind(renderer, frameBuffer);
|
||||
// MRT Support in chrome
|
||||
// https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
|
||||
const ext = renderer.getGLExtension('EXT_draw_buffers');
|
||||
if (ext && this.outputs) {
|
||||
const bufs = [];
|
||||
for (let attachment in this.outputs) {
|
||||
attachment = +attachment;
|
||||
if (attachment >= _gl.COLOR_ATTACHMENT0 && attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
|
||||
bufs.push(attachment);
|
||||
}
|
||||
}
|
||||
ext.drawBuffersEXT(bufs);
|
||||
}
|
||||
}
|
||||
|
||||
this.trigger('beforerender', this, renderer);
|
||||
|
||||
// FIXME Don't clear in each pass in default, let the color overwrite the buffer
|
||||
// FIXME pixels may be discard
|
||||
let clearBit = this.clearDepth ? _gl.DEPTH_BUFFER_BIT : 0;
|
||||
_gl.depthMask(true);
|
||||
if (this.clearColor) {
|
||||
clearBit = clearBit | _gl.COLOR_BUFFER_BIT;
|
||||
_gl.colorMask(true, true, true, true);
|
||||
const cc = this.clearColor;
|
||||
if (Array.isArray(cc)) {
|
||||
_gl.clearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||
}
|
||||
}
|
||||
_gl.clear(clearBit);
|
||||
|
||||
if (this.blendWithPrevious) {
|
||||
// Blend with previous rendered scene in the final output
|
||||
// FIXME Configure blend.
|
||||
// FIXME It will cause screen blink?
|
||||
_gl.enable(_gl.BLEND);
|
||||
this.material.transparent = true;
|
||||
} else {
|
||||
_gl.disable(_gl.BLEND);
|
||||
this.material.transparent = false;
|
||||
}
|
||||
|
||||
this.renderQuad(renderer);
|
||||
|
||||
this.trigger('afterrender', this, renderer);
|
||||
|
||||
if (frameBuffer) {
|
||||
this.unbind(renderer, frameBuffer);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Simply do quad rendering
|
||||
*/
|
||||
renderQuad: function (renderer) {
|
||||
mesh.material = this.material;
|
||||
renderer.renderPass([mesh], camera);
|
||||
},
|
||||
|
||||
/**
|
||||
* @param {clay.Renderer} renderer
|
||||
*/
|
||||
dispose: function (renderer) {}
|
||||
opts = opts || {};
|
||||
this.clearColor = opts.clearColor || false;
|
||||
this.blendWithPrevious = opts.blendWithPrevious || false;
|
||||
this.clearDepth = optional(opts.clearColor, true);
|
||||
}
|
||||
);
|
||||
|
||||
export default Pass;
|
||||
setUniform(name: string, value: any) {
|
||||
this.material.setUniform(name, value);
|
||||
}
|
||||
getUniform(name: string) {
|
||||
const uniform = this.material.uniforms[name];
|
||||
if (uniform) {
|
||||
return uniform.value;
|
||||
}
|
||||
}
|
||||
attachOutput(texture: Texture2D, attachment?: GLEnum) {
|
||||
if (!this.outputs) {
|
||||
this.outputs = {};
|
||||
}
|
||||
attachment = attachment || glenum.COLOR_ATTACHMENT0;
|
||||
this.outputs[attachment] = texture;
|
||||
}
|
||||
/**
|
||||
* @param {clay.Texture} texture
|
||||
*/
|
||||
detachOutput(texture: Texture2D) {
|
||||
for (const attachment in this.outputs) {
|
||||
if (this.outputs[attachment] === texture) {
|
||||
this.outputs[attachment] = undefined;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bind(renderer: Renderer, frameBuffer: FrameBuffer) {
|
||||
for (const attachment in this.outputs) {
|
||||
const texture = this.outputs[attachment];
|
||||
if (texture) {
|
||||
frameBuffer.attach(texture, +attachment);
|
||||
}
|
||||
}
|
||||
|
||||
if (frameBuffer) {
|
||||
frameBuffer.bind(renderer);
|
||||
}
|
||||
}
|
||||
|
||||
unbind(renderer: Renderer, frameBuffer: FrameBuffer) {
|
||||
frameBuffer.unbind(renderer);
|
||||
}
|
||||
|
||||
render(renderer: Renderer, frameBuffer: FrameBuffer) {
|
||||
const _gl = renderer.gl;
|
||||
|
||||
if (frameBuffer) {
|
||||
this.bind(renderer, frameBuffer);
|
||||
// MRT Support in chrome
|
||||
// https://www.khronos.org/registry/webgl/sdk/tests/conformance/extensions/ext-draw-buffers.html
|
||||
const ext = renderer.getGLExtension('EXT_draw_buffers');
|
||||
if (ext && this.outputs) {
|
||||
const bufs = [];
|
||||
for (const attachment in this.outputs) {
|
||||
if (+attachment >= _gl.COLOR_ATTACHMENT0 && +attachment <= _gl.COLOR_ATTACHMENT0 + 8) {
|
||||
bufs.push(attachment);
|
||||
}
|
||||
}
|
||||
ext.drawBuffersEXT(bufs);
|
||||
}
|
||||
}
|
||||
|
||||
this.trigger('beforerender', this, renderer);
|
||||
|
||||
// FIXME Don't clear in each pass in default, let the color overwrite the buffer
|
||||
// FIXME pixels may be discard
|
||||
let clearBit = this.clearDepth ? _gl.DEPTH_BUFFER_BIT : 0;
|
||||
_gl.depthMask(true);
|
||||
if (this.clearColor) {
|
||||
clearBit = clearBit | _gl.COLOR_BUFFER_BIT;
|
||||
_gl.colorMask(true, true, true, true);
|
||||
const cc = this.clearColor;
|
||||
if (Array.isArray(cc)) {
|
||||
_gl.clearColor(cc[0], cc[1], cc[2], cc[3]);
|
||||
}
|
||||
}
|
||||
_gl.clear(clearBit);
|
||||
|
||||
if (this.blendWithPrevious) {
|
||||
// Blend with previous rendered scene in the final output
|
||||
// FIXME Configure blend.
|
||||
// FIXME It will cause screen blink?
|
||||
_gl.enable(_gl.BLEND);
|
||||
this.material.transparent = true;
|
||||
} else {
|
||||
_gl.disable(_gl.BLEND);
|
||||
this.material.transparent = false;
|
||||
}
|
||||
|
||||
this.renderQuad(renderer);
|
||||
|
||||
this.trigger('afterrender', this, renderer);
|
||||
|
||||
if (frameBuffer) {
|
||||
this.unbind(renderer, frameBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Simply do quad rendering
|
||||
*/
|
||||
renderQuad(renderer: Renderer) {
|
||||
mesh.material = this.material;
|
||||
renderer.renderPass([mesh], camera);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {clay.Renderer} renderer
|
||||
*/
|
||||
dispose(renderer: Renderer) {}
|
||||
}
|
||||
|
||||
export default CompositorFullscreenQuadPass;
|
||||
|
||||
@ -1,18 +1,14 @@
|
||||
// @ts-nocheck
|
||||
import Texture2D from '../Texture2D';
|
||||
import glenum from '../core/glenum';
|
||||
import * as util from '../core/util';
|
||||
import Texture, { TextureOpts } from '../Texture';
|
||||
import Renderer from '../Renderer';
|
||||
|
||||
const TexturePool = function () {
|
||||
this._pool = {};
|
||||
class TexturePool {
|
||||
private _pool: Record<string, Texture[]> = {};
|
||||
private _allocatedTextures: Texture[] = [];
|
||||
|
||||
this._allocatedTextures = [];
|
||||
};
|
||||
|
||||
TexturePool.prototype = {
|
||||
constructor: TexturePool,
|
||||
|
||||
get: function (parameters) {
|
||||
get(parameters: Partial<TextureOpts>) {
|
||||
const key = generateKey(parameters);
|
||||
if (!util.hasOwn(this._pool, key)) {
|
||||
this._pool[key] = [];
|
||||
@ -24,27 +20,26 @@ TexturePool.prototype = {
|
||||
return texture;
|
||||
}
|
||||
return list.pop();
|
||||
},
|
||||
}
|
||||
|
||||
put: function (texture) {
|
||||
put(texture: Texture) {
|
||||
const key = generateKey(texture);
|
||||
if (!util.hasOwn(this._pool, key)) {
|
||||
this._pool[key] = [];
|
||||
}
|
||||
const list = this._pool[key];
|
||||
list.push(texture);
|
||||
},
|
||||
}
|
||||
|
||||
clear: function (renderer) {
|
||||
clear(renderer: Renderer) {
|
||||
for (let i = 0; i < this._allocatedTextures.length; i++) {
|
||||
this._allocatedTextures[i].dispose(renderer);
|
||||
}
|
||||
this._pool = {};
|
||||
this._allocatedTextures = [];
|
||||
}
|
||||
};
|
||||
|
||||
const defaultParams = {
|
||||
}
|
||||
const defaultParams: Partial<TextureOpts> = {
|
||||
width: 512,
|
||||
height: 512,
|
||||
type: glenum.UNSIGNED_BYTE,
|
||||
@ -58,24 +53,22 @@ const defaultParams = {
|
||||
flipY: true,
|
||||
unpackAlignment: 4,
|
||||
premultiplyAlpha: false
|
||||
};
|
||||
} as const;
|
||||
|
||||
const defaultParamPropList = Object.keys(defaultParams);
|
||||
|
||||
function generateKey(parameters) {
|
||||
util.defaultsWithPropList(parameters, defaultParams, defaultParamPropList);
|
||||
function generateKey(parameters: Partial<TextureOpts>) {
|
||||
util.defaults(parameters, defaultParams);
|
||||
fallBack(parameters);
|
||||
|
||||
let key = '';
|
||||
for (let i = 0; i < defaultParamPropList.length; i++) {
|
||||
const name = defaultParamPropList[i];
|
||||
const chunk = parameters[name].toString();
|
||||
key += chunk;
|
||||
key += (parameters as any)[defaultParamPropList[i]].toString();
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
function fallBack(target) {
|
||||
function fallBack(target: any) {
|
||||
const IPOT = isPowerOfTwo(target.width, target.height);
|
||||
|
||||
if (target.format === glenum.DEPTH_COMPONENT) {
|
||||
@ -101,7 +94,7 @@ function fallBack(target) {
|
||||
}
|
||||
}
|
||||
|
||||
function isPowerOfTwo(width, height) {
|
||||
function isPowerOfTwo(width: number, height: number) {
|
||||
return (width & (width - 1)) === 0 && (height & (height - 1)) === 0;
|
||||
}
|
||||
|
||||
|
||||
8
src/core/index.ts
Normal file
8
src/core/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import * as color from './color';
|
||||
import LinkedList from './LinkedList';
|
||||
import LRU from './LRU';
|
||||
import Notifier from './Notifier';
|
||||
import * as request from './request';
|
||||
import * as util from './util';
|
||||
|
||||
export { color, LinkedList, LRU, Notifier, request, util };
|
||||
@ -23,7 +23,6 @@ class ConeGeometry extends Geometry {
|
||||
heightSegments = 1;
|
||||
|
||||
constructor(opts?: Partial<ConeGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
@ -23,7 +23,6 @@ class CubeGeometry extends Geometry {
|
||||
inside = false;
|
||||
|
||||
constructor(opts?: Partial<CubeGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
@ -16,7 +16,6 @@ class CylinderGeometry extends Geometry {
|
||||
heightSegments = 1;
|
||||
|
||||
constructor(opts?: Partial<CylinderGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
@ -18,7 +18,6 @@ class ParametricSurfaceGeometry extends Geometry {
|
||||
generator: SurfaceGenerator;
|
||||
|
||||
constructor(opts?: Partial<ParametricSurfaceGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
@ -12,7 +12,6 @@ class PlaneGeometry extends Geometry {
|
||||
heightSegments = 1;
|
||||
|
||||
constructor(opts?: Partial<PlaneGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
@ -26,7 +26,6 @@ class SphereGeometry extends Geometry {
|
||||
radius = 1;
|
||||
|
||||
constructor(opts?: Partial<SphereGeometryOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
Object.assign(this, opts);
|
||||
this.build();
|
||||
|
||||
8
src/geometry/index.ts
Normal file
8
src/geometry/index.ts
Normal file
@ -0,0 +1,8 @@
|
||||
import Cone from './Cone';
|
||||
import Cube from './Cube';
|
||||
import Cylinder from './Cylinder';
|
||||
import ParametricSurface from './ParametricSurface';
|
||||
import Plane from './Plane';
|
||||
import Sphere from './Sphere';
|
||||
|
||||
export { Cone, Cube, Cylinder, ParametricSurface, Plane, Sphere };
|
||||
@ -502,7 +502,7 @@ export const forEach = (function () {
|
||||
for (i = offset; i < l; i += stride) {
|
||||
vec[0] = a[i];
|
||||
vec[1] = a[i + 1];
|
||||
fn(vec, vec, arg);
|
||||
fn(vec, vec, arg as T);
|
||||
a[i] = vec[0];
|
||||
a[i + 1] = vec[1];
|
||||
}
|
||||
|
||||
@ -627,7 +627,7 @@ export const forEach = (function () {
|
||||
vec[0] = a[i];
|
||||
vec[1] = a[i + 1];
|
||||
vec[2] = a[i + 2];
|
||||
fn(vec, vec, arg);
|
||||
fn(vec, vec, arg as T);
|
||||
a[i] = vec[0];
|
||||
a[i + 1] = vec[1];
|
||||
a[i + 2] = vec[2];
|
||||
|
||||
@ -521,7 +521,7 @@ export const forEach = (function () {
|
||||
vec[1] = a[i + 1];
|
||||
vec[2] = a[i + 2];
|
||||
vec[3] = a[i + 3];
|
||||
fn(vec, vec, arg);
|
||||
fn(vec, vec, arg as T);
|
||||
a[i] = vec[0];
|
||||
a[i + 1] = vec[1];
|
||||
a[i + 2] = vec[2];
|
||||
|
||||
@ -44,7 +44,9 @@ function unrollLoop(
|
||||
// PENDING Add scope?
|
||||
unroll +=
|
||||
'{' +
|
||||
snippet.replace(/float\s*\(\s*_idx_\s*\)/g, idx.toFixed(1)).replace(/_idx_/g, idx) +
|
||||
snippet
|
||||
.replace(/float\s*\(\s*_idx_\s*\)/g, idx.toFixed(1))
|
||||
.replace(/_idx_/g, idx as any as string) +
|
||||
'}';
|
||||
}
|
||||
|
||||
|
||||
@ -27,10 +27,8 @@ class AmbientCubemapLight extends Light {
|
||||
readonly type = 'AMBIENT_CUBEMAP_LIGHT';
|
||||
|
||||
constructor(opts?: Partial<AmbientCubemapLightOpts>) {
|
||||
opts = opts || {};
|
||||
|
||||
super(opts);
|
||||
this.cubemap = opts.cubemap;
|
||||
this.cubemap = opts && opts.cubemap;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@ -10,9 +10,8 @@ class AmbientSHLight extends Light {
|
||||
|
||||
__coefficientsTmpArr = new Float32Array(9 * 3);
|
||||
constructor(opts?: Partial<AmbientSHLightOpts>) {
|
||||
opts = opts || {};
|
||||
super(opts);
|
||||
this.coefficients = opts.coefficients || [];
|
||||
this.coefficients = (opts && opts.coefficients) || [];
|
||||
}
|
||||
|
||||
clone() {
|
||||
|
||||
10
src/light/index.ts
Normal file
10
src/light/index.ts
Normal file
@ -0,0 +1,10 @@
|
||||
import Ambient from './Ambient';
|
||||
import AmbientCubemap from './AmbientCubemap';
|
||||
import AmbientSH from './AmbientSH';
|
||||
import Directional from './Directional';
|
||||
import Point from './Point';
|
||||
import Sphere from './Sphere';
|
||||
import Spot from './Spot';
|
||||
import Tube from './Tube';
|
||||
|
||||
export { Ambient, AmbientCubemap, AmbientSH, Directional, Point, Sphere, Spot, Tube };
|
||||
@ -25,7 +25,7 @@ import glenum from '../core/glenum';
|
||||
|
||||
import BoundingBox from '../math/BoundingBox';
|
||||
|
||||
import TrackAnimator from '../animation/TrackAnimator';
|
||||
import TrackAnimation from '../animation/TrackAnimation';
|
||||
import SamplerTrack from '../animation/SamplerTrack';
|
||||
|
||||
import Geometry from '../Geometry';
|
||||
@ -1283,7 +1283,7 @@ const GLTFLoader = Base.extend(
|
||||
for (const hash in tracks) {
|
||||
tracksList.push(tracks[hash]);
|
||||
}
|
||||
const clip = new TrackAnimator({
|
||||
const clip = new TrackAnimation({
|
||||
name: animationInfo.name,
|
||||
loop: true,
|
||||
tracks: tracksList
|
||||
|
||||
27
src/math/index.ts
Normal file
27
src/math/index.ts
Normal file
@ -0,0 +1,27 @@
|
||||
import Frustum from './Frustum';
|
||||
import Matrix2 from './Matrix2';
|
||||
import Matrix2d from './Matrix2d';
|
||||
import Matrix3 from './Matrix3';
|
||||
import Matrix4 from './Matrix4';
|
||||
import Plane from './Plane';
|
||||
import Quaternion from './Quaternion';
|
||||
import Ray from './Ray';
|
||||
import * as Value from './Value';
|
||||
import Vector2 from './Vector2';
|
||||
import Vector3 from './Vector3';
|
||||
import Vector4 from './Vector4';
|
||||
|
||||
export {
|
||||
Frustum,
|
||||
Matrix2,
|
||||
Matrix2d,
|
||||
Matrix3,
|
||||
Matrix4,
|
||||
Plane,
|
||||
Quaternion,
|
||||
Ray,
|
||||
Value,
|
||||
Vector2,
|
||||
Vector3,
|
||||
Vector4
|
||||
};
|
||||
@ -1,16 +1,42 @@
|
||||
// @ts-nocheck
|
||||
import Base from '../core/Base';
|
||||
import Vector3 from '../math/Vector3';
|
||||
import PerspectiveCamera from '../camera/Perspective';
|
||||
import FrameBuffer from '../FrameBuffer';
|
||||
import TextureCube from '../TextureCube';
|
||||
|
||||
const targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
|
||||
import type ShadowMapPass from './ShadowMap';
|
||||
import type Renderer from '../Renderer';
|
||||
import type Scene from '../Scene';
|
||||
|
||||
const targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'] as const;
|
||||
|
||||
type CameraTarget = typeof targets[number];
|
||||
|
||||
interface EnvironmentMapPassOpts {
|
||||
/**
|
||||
* Camera position
|
||||
*/
|
||||
position: Vector3;
|
||||
/**
|
||||
* Camera far plane
|
||||
*/
|
||||
far: number;
|
||||
/**
|
||||
* Camera near plane
|
||||
*/
|
||||
near: number;
|
||||
/**
|
||||
* Environment cube map
|
||||
*/
|
||||
texture: TextureCube;
|
||||
|
||||
/**
|
||||
* Used if you wan't have shadow in environment map
|
||||
*/
|
||||
shadowMapPass: ShadowMapPass;
|
||||
}
|
||||
/**
|
||||
* Pass rendering scene to a environment cube map
|
||||
*
|
||||
* @constructor clay.prePass.EnvironmentMap
|
||||
* @extends clay.core.Base
|
||||
* @example
|
||||
* // Example of car reflection
|
||||
* const envMap = new clay.TextureCube({
|
||||
@ -30,41 +56,36 @@ const targets = ['px', 'nx', 'py', 'ny', 'pz', 'nz'];
|
||||
* renderer.render(scene, camera);
|
||||
* });
|
||||
*/
|
||||
const EnvironmentMapPass = Base.extend(
|
||||
function () {
|
||||
const ret = /** @lends clay.prePass.EnvironmentMap# */ {
|
||||
/**
|
||||
* Camera position
|
||||
* @type {clay.Vector3}
|
||||
* @memberOf clay.prePass.EnvironmentMap#
|
||||
*/
|
||||
position: new Vector3(),
|
||||
/**
|
||||
* Camera far plane
|
||||
* @type {number}
|
||||
* @memberOf clay.prePass.EnvironmentMap#
|
||||
*/
|
||||
far: 1000,
|
||||
/**
|
||||
* Camera near plane
|
||||
* @type {number}
|
||||
* @memberOf clay.prePass.EnvironmentMap#
|
||||
*/
|
||||
near: 0.1,
|
||||
/**
|
||||
* Environment cube map
|
||||
* @type {clay.TextureCube}
|
||||
* @memberOf clay.prePass.EnvironmentMap#
|
||||
*/
|
||||
texture: null,
|
||||
class EnvironmentMapPass {
|
||||
/**
|
||||
* Camera position
|
||||
*/
|
||||
position = new Vector3();
|
||||
/**
|
||||
* Camera far plane
|
||||
*/
|
||||
far = 1000;
|
||||
/**
|
||||
* Camera near plane
|
||||
*/
|
||||
near = 0.1;
|
||||
/**
|
||||
* Environment cube map
|
||||
*/
|
||||
texture?: TextureCube;
|
||||
|
||||
/**
|
||||
* Used if you wan't have shadow in environment map
|
||||
* @type {clay.prePass.ShadowMap}
|
||||
*/
|
||||
shadowMapPass: null
|
||||
};
|
||||
const cameras = (ret._cameras = {
|
||||
/**
|
||||
* Used if you wan't have shadow in environment map
|
||||
*/
|
||||
shadowMapPass?: ShadowMapPass;
|
||||
|
||||
private _cameras: Record<CameraTarget, PerspectiveCamera>;
|
||||
private _frameBuffer: FrameBuffer;
|
||||
|
||||
constructor(opts?: Partial<EnvironmentMapPassOpts>) {
|
||||
Object.assign(this, opts);
|
||||
|
||||
const cameras = (this._cameras = {
|
||||
px: new PerspectiveCamera({ fov: 90 }),
|
||||
nx: new PerspectiveCamera({ fov: 90 }),
|
||||
py: new PerspectiveCamera({ fov: 90 }),
|
||||
@ -80,69 +101,53 @@ const EnvironmentMapPass = Base.extend(
|
||||
cameras.nz.lookAt(Vector3.NEGATIVE_Z, Vector3.NEGATIVE_Y);
|
||||
|
||||
// FIXME In windows, use one framebuffer only renders one side of cubemap
|
||||
ret._frameBuffer = new FrameBuffer();
|
||||
this._frameBuffer = new FrameBuffer();
|
||||
}
|
||||
getCamera(target: CameraTarget) {
|
||||
return this._cameras[target];
|
||||
}
|
||||
render(renderer: Renderer, scene: Scene, notUpdateScene?: boolean) {
|
||||
const _gl = renderer.gl;
|
||||
const texture = this.texture;
|
||||
if (!notUpdateScene) {
|
||||
scene.update();
|
||||
}
|
||||
if (!texture) {
|
||||
console.error('texture not provided');
|
||||
return;
|
||||
}
|
||||
// Tweak fov
|
||||
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
|
||||
const n = texture.width;
|
||||
const fov = ((2 * Math.atan(n / (n - 0.5))) / Math.PI) * 180;
|
||||
|
||||
return ret;
|
||||
},
|
||||
/** @lends clay.prePass.EnvironmentMap# */ {
|
||||
/**
|
||||
* @param {string} target
|
||||
* @return {clay.Camera}
|
||||
*/
|
||||
getCamera: function (target) {
|
||||
return this._cameras[target];
|
||||
},
|
||||
/**
|
||||
* @param {clay.Renderer} renderer
|
||||
* @param {clay.Scene} scene
|
||||
* @param {boolean} [notUpdateScene=false]
|
||||
*/
|
||||
render: function (renderer, scene, notUpdateScene) {
|
||||
const _gl = renderer.gl;
|
||||
if (!notUpdateScene) {
|
||||
scene.update();
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const target = targets[i];
|
||||
const camera = this._cameras[target];
|
||||
Vector3.copy(camera.position, this.position);
|
||||
|
||||
camera.far = this.far;
|
||||
camera.near = this.near;
|
||||
camera.fov = fov;
|
||||
|
||||
if (this.shadowMapPass) {
|
||||
camera.update();
|
||||
|
||||
// update boundingBoxLastFrame
|
||||
const bbox = scene.getBoundingBox();
|
||||
bbox.applyTransform(camera.viewMatrix);
|
||||
scene.viewBoundingBoxLastFrame.copy(bbox);
|
||||
|
||||
this.shadowMapPass.render(renderer, scene, camera, true);
|
||||
}
|
||||
// Tweak fov
|
||||
// http://the-witness.net/news/2012/02/seamless-cube-map-filtering/
|
||||
const n = this.texture.width;
|
||||
const fov = ((2 * Math.atan(n / (n - 0.5))) / Math.PI) * 180;
|
||||
|
||||
for (let i = 0; i < 6; i++) {
|
||||
const target = targets[i];
|
||||
const camera = this._cameras[target];
|
||||
Vector3.copy(camera.position, this.position);
|
||||
|
||||
camera.far = this.far;
|
||||
camera.near = this.near;
|
||||
camera.fov = fov;
|
||||
|
||||
if (this.shadowMapPass) {
|
||||
camera.update();
|
||||
|
||||
// update boundingBoxLastFrame
|
||||
const bbox = scene.getBoundingBox();
|
||||
bbox.applyTransform(camera.viewMatrix);
|
||||
scene.viewBoundingBoxLastFrame.copy(bbox);
|
||||
|
||||
this.shadowMapPass.render(renderer, scene, camera, true);
|
||||
}
|
||||
this._frameBuffer.attach(
|
||||
this.texture,
|
||||
_gl.COLOR_ATTACHMENT0,
|
||||
_gl.TEXTURE_CUBE_MAP_POSITIVE_X + i
|
||||
);
|
||||
this._frameBuffer.bind(renderer);
|
||||
renderer.render(scene, camera, true);
|
||||
this._frameBuffer.unbind(renderer);
|
||||
}
|
||||
},
|
||||
/**
|
||||
* @param {clay.Renderer} renderer
|
||||
*/
|
||||
dispose: function (renderer) {
|
||||
this._frameBuffer.dispose(renderer);
|
||||
this._frameBuffer.attach(texture, _gl.COLOR_ATTACHMENT0, _gl.TEXTURE_CUBE_MAP_POSITIVE_X + i);
|
||||
this._frameBuffer.bind(renderer);
|
||||
renderer.render(scene, camera, true);
|
||||
this._frameBuffer.unbind(renderer);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
dispose(renderer: Renderer) {
|
||||
this._frameBuffer.dispose(renderer);
|
||||
}
|
||||
}
|
||||
export default EnvironmentMapPass;
|
||||
|
||||
@ -5,13 +5,12 @@ import Texture2D from '../Texture2D';
|
||||
import TextureCube, { TextureCubeOpts } from '../TextureCube';
|
||||
import Texture from '../Texture';
|
||||
import FrameBuffer from '../FrameBuffer';
|
||||
import Pass from '../compositor/Pass';
|
||||
import CompositorFullscreenQuadPass from '../compositor/Pass';
|
||||
import Material from '../Material';
|
||||
import Shader from '../Shader';
|
||||
import Skybox from '../plugin/Skybox';
|
||||
import Scene from '../Scene';
|
||||
import EnvironmentMapPass from '../prePass/EnvironmentMap';
|
||||
import vendor from '../core/vendor';
|
||||
import textureUtil from './texture';
|
||||
|
||||
import integrateBRDFShaderCode from './shader/integrateBRDF.glsl.js';
|
||||
@ -50,9 +49,9 @@ export function prefilterEnvironmentMap(
|
||||
width: width,
|
||||
height: height,
|
||||
type: textureType,
|
||||
flipY: false,
|
||||
mipmaps: []
|
||||
flipY: false
|
||||
});
|
||||
prefilteredCubeMap.mipmaps = [];
|
||||
|
||||
if (!prefilteredCubeMap.isPowerOfTwo()) {
|
||||
console.warn('Width and height must be power of two to enable mipmap.');
|
||||
@ -184,9 +183,7 @@ export function integrateBRDF(renderer: Renderer, normalDistribution: Texture2D)
|
||||
const framebuffer = new FrameBuffer({
|
||||
depthBuffer: false
|
||||
});
|
||||
const pass = new Pass({
|
||||
fragment: integrateBRDFShaderCode
|
||||
});
|
||||
const quadPass = new CompositorFullscreenQuadPass(integrateBRDFShaderCode);
|
||||
|
||||
const texture = new Texture2D({
|
||||
width: 512,
|
||||
@ -198,10 +195,10 @@ export function integrateBRDF(renderer: Renderer, normalDistribution: Texture2D)
|
||||
magFilter: Texture.NEAREST,
|
||||
useMipmap: false
|
||||
});
|
||||
pass.setUniform('normalDistribution', normalDistribution);
|
||||
pass.setUniform('viewportSize', [512, 256]);
|
||||
pass.attachOutput(texture);
|
||||
pass.render(renderer, framebuffer);
|
||||
quadPass.setUniform('normalDistribution', normalDistribution);
|
||||
quadPass.setUniform('viewportSize', [512, 256]);
|
||||
quadPass.attachOutput(texture);
|
||||
quadPass.render(renderer, framebuffer);
|
||||
|
||||
// FIXME Only chrome and firefox can readPixels with float type.
|
||||
// framebuffer.bind(renderer);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user